No port numbers
Real names like frontend.my-feature.localhost instead of localhost:3847.
Real HTTPS URLs for every service you run — one command, no YAML, no cloud bill. Then you and your coding agent build on it, together.
# declare it once, then start a service:
veld orchestrator start frontend:local
=> https://frontend.my-feature.myproject.localhost
=> https://backend.my-feature.myproject.localhost
# …or spin up a whole preset — by name, or the number veld shows you:
veld orchestrator start --preset fullstack
# hand it to a colleague on the web — no Veld on their end:
veld network share --web
=> https://frontend-a1b2c3.share.yourteam.dev (password: cheerful-otter-42)
The run name is inferred from your git branch — no --name needed (pass one to override).
100% vibe coded with Claude Code. MIT licensed. macOS & Linux.
Everything it does. No demo to sit through.
Real names like frontend.my-feature.localhost instead of localhost:3847.
Works out what depends on what, starts it all (in parallel where it can), and shuts down cleanly in reverse.
Point veld orchestrator start --oneshot at a test command: it spins up every service the tests need, runs them, prints the results, then tears it all down — and the test's exit code becomes veld's. One line in CI.
Every URL is https:// with a trusted certificate. Set up once — no browser warnings.
You don't get a URL until the service actually responds — and veld keeps watching after it's up. Not everything in a dev environment is a web server, either: a file watcher, a background compiler, a desktop shell can all sit in the same graph, supervised and torn down with the rest, with no port and no URL.
If a service falls over, veld brings the environment back on its own. Every run leaves a record: when it ran, how it ended, and its logs — so veld orchestrator runs list answers "why did last night's run die?" days later.
Run a service locally, in Docker, or against a remote — and start your go-to combinations with one short name. Give each a number that never moves when someone adds another, and a line saying who it’s for, so “which one do I run?” has an answer for the designer and the coding agent.
Comments where you need them — call the file veld.jsonc and your editor stops arguing. Split it across per-directory files so each team owns theirs. Say a value once and reference it everywhere. It deduplicates values, never structure — so opening a service’s file still tells you what it runs, and grepping for an env var still finds the line that sets it.
Write it as a list and veld runs it directly. A password with a space in it stays one argument — not two arguments and an incident. Want a pipe? Ask for a shell.
veld holds a pointer, not your password: an env var, a file, or a command that prints one. Mark it secret and it refuses to put it on a command line, where ps would read it out to the whole machine.
Some values in a checked-in config aren’t project facts, they’re machine facts — which container runtime you have, how much memory this machine can spare, where a tool lives. Declare a default, and each person answers once with veld orchestrator vars set. Kept per machine and shared across all your worktrees, so you answer it once, not once per checkout.
veld orchestrator lint lists every problem at once and fails CI. Typo’d variable, one that is real but means nothing where you wrote it, a preset pointing at a node that moved, a service reading a URL that only exists under some presets, secret about to leak. Better now than 9am Monday.
Give every branch or git worktree its own environment — they run in parallel without clashing. Re-running by name just resumes.
Every command has a --json mode for CI, scripts, and coding agents.
See health, per-service memory & CPU, tail logs, search, browse past runs, and stop/restart — all at veld.localhost.
Adding up a process tree’s memory double-counts everything its processes share, so Veld reports the real footprint instead. Expand a service for a scrubbable graph of memory or CPU — by memory type, or by which subprocess is eating it.
Measuring starts when the run does, not when it finishes. Your build steps and installs are graphed while they run, and a dev server’s startup ramp is recorded — so “why does this need 12 GB” is a question you can answer.
Captures the app's console logs and crashes so you can read them from the CLI.
You move the test command; everyone else finds out when it breaks for them. Write a short note into the project’s config alongside the change — a headline and one sentence — and each teammate is told once, the next time they open the IDE. Capped at five notes and 44 characters of headline, so it stays worth reading.
Long builds and overnight agents die when the machine suspends. One button in the top bar holds it awake — for 30 minutes, a few hours, or until you say otherwise — and lets go the moment Veld does, so nothing is left pinned on. Shut the lid and walk away: on Linux, and on a Mac set up with veld self setup privileged, that works on battery too. Sharing does it for you without being asked, capped, and asked separately for mains and battery — but it will never hold the lid shut on battery unless you say so yourself.
Send a colleague an encrypted link; they open the same URLs on their machine. No accounts, no server.
veld network share --web gives you a real public URL — the other person doesn't need Veld at all.
Ask for a slide deck or an analysis written as HTML and you used to leave for Chrome to look at it. Run open deck.html in a Veld terminal, or pick it off a newest-first list showing what changed and how long ago, and it opens in a pane beside the shell that made it — then reloads itself each time that file changes — including one you reached by a link out of it, so a set of decks that link to each other behaves like one document. Served over HTTP from an origin of its own, so module scripts and fetch work where a file:// URL would render the page blank.
A plan, a CSV, the function it wants you to look at: the agent runs veld ide open plan.md --notify and it opens beside its terminal — markdown rendered, tables sortable, code highlighted with this branch’s changes in the gutter — and the worktree is marked until you’ve looked. Agents started in a Veld terminal are told they can. Select a few lines and copy them as plan.md:12-18 with the excerpt, ready to paste back. Read-only on purpose: your editor is still where you edit.
What you'll actually type: veld <part> <verb>. Bare veld shows what is up and who needs you, veld --help-all lists every command, and an old name such as veld start tells you where it went. orc works for orchestrator. Every one speaks --json.
veld orchestrator start NODE:VARIANT --name NStart an environmentveld orchestrator start --preset NAME|KEYStart a preset — a saved selection of nodes (e.g. fullstack). Or just veld orchestrator start and pick from the listveld orchestrator start NODE --oneshotRun a command node as a one-off — start its deps, run it to completion, tear down, exit with its code (e.g. e2e tests)veld orchestrator stop [--name N] [--all]Stop a running environmentveld orchestrator restart [--name N]Restart an environmentveld orchestrator status [--name N]Show run statusveld orchestrator stats [--processes] [--history] [--cpu]Detailed CPU & memory — split by memory type and by subprocess, with historyveld orchestrator urls [--name N]Show URLs for a runveld orchestrator logs [-f] [-s TERM] [--run ID]View logs (follow, search, source filter — including past runs)veld orchestrator graph / nodes / presets / runs listInspect the config and the run historyveld orchestrator lintCheck the config for problems — every one at once, exits non-zero in CIveld orchestrator config --files / --why PWhich file defines which node, and where an effective value came fromveld orchestrator vars list / set / unsetValues that differ per machine — answered once, shared across your worktreesveld orchestrator action NAMERun a node-defined action (e.g. open the DB in a GUI)veld orchestrator initCreate a new veld.json (veld reads veld.jsonc too)veld ide dashboardOpen the management dashboardveld ide open PATH|URL --notify|--quietShow a file or a page in the Veld window, beside the terminal that asked (agent-facing)veld ide worktree new --branch B --name T --prompt-file FHand a task to the human: a new worktree whose agent starts on that prompt when they open it (agent-facing)veld agent skills [TOPIC]The agent documentation this binary carries — one topic at a timeveld network share [RUN] [--web]Share a run over an encrypted P2P tunnel (or the open web)veld network join TICKETJoin a shared env; the same URLs materialize locallyveld network listList shares, joins, and pending requests with transport infoveld network approve / deny REQGate who connects to your shareveld network unshare / leaveStop hosting, or disconnect from a joined shareveld self settings list / get / set / unset / describeVeld’s own preferences from the terminal — describe gives an agent the type, default and allowed valuesveld self setup [privileged]One-time system setup (clean URLs need privileged; unprivileged is no-sudo)veld self doctor / gcCheck extension status; clean up stale stateveld self backup list / now / restoreCopies of veld's own state database, and putting one back — and it says when copies have stopped being writtenOne line. No sudo. Detects your OS and architecture.
curl -fsSL https://veld.oss.life.li/get | bash
This installs veld to ~/.local/bin. Commands auto-bootstrap on first use with HTTPS on port 18443. For clean URLs with no port suffix, run the one-time veld self setup privileged — sudo once, never again. Prefer no sudo at all? veld self setup unprivileged supports the full feature set on .localhost domains.
Upgrading from an older veld? Your veld.json needs "schemaVersion": "3" — earlier versions no longer load. It is a handful of lines, and the error you get names every change: the migration guide is written so you can hand it to your coding agent, then run veld orchestrator lint to check the result.
veld isn't just something your coding agent can drive — it's where the two of you meet. --json on every command, an llms.txt it can read, and a skill so it knows the ropes.
npx skills add prosperity-solutions/veld
Installs the veld skill for Claude Code, Cursor, Codex, Windsurf, and 40+ more — so your agent can configure, run, and share environments without you narrating each step.
The skill is a pointer, a few kilobytes. The documentation ships inside the binary, so your agent reads the docs for the veld you actually have — and reads only the page it needs, when it needs it, instead of loading a manual and your whole config into its context first.
# the index — thirteen topics, one line each:
veld agent skills
# then just the page the task needs:
veld agent skills basics
veld agent skills config
Nothing to re-install when veld updates: the skill never changes, because it only says where to look.
A new checkout in the IDE can start with a prompt instead of a name. Pick one of the project’s agents, say what needs doing, and it is already working when the worktree opens — on its own branch, beside everything else you have running. Drop a screenshot or a JSON file anywhere on the dialog and it goes in with the prompt, the way it would if you dropped it on the agent yourself. Name, branch, colour and glyph are all still there in the other mode, and none of them is required. The agent names the checkout itself, with veld ide worktree name, once it knows what the task is.
For the nerds. A few small Rust binaries, one config file, and Caddy for HTTPS — that's the whole thing.
The CLI. A thin client: sends your command to the engine in the daemon, draws the progress it streams back, and starts the daemon if it isn't running.
User-space daemon. Hosts the engine that starts, stops and restarts environments (each action in a worker process that outlives daemon restarts), monitors health, runs garbage collection, broadcasts state updates.
Manages DNS entries and Caddy routes over a minimal Unix socket. Privileged or unprivileged.
Public web gateway (one Docker container). Joins a share over iroh and reverse-proxies it onto a public URL.
Shared P2P transport built on iroh (QUIC, NAT hole-punching). Used by the daemon and the gateway.
All state — runs, registry, logs, tokens — in one WAL-mode database. Versioned, migrates forward. Backed up on an interval, integrity-checked on a timer, and restorable in one click when it isn't.
veld network share connects your daemon straight to a colleague's Veld over an encrypted iroh tunnel — no gateway in the path (an optional self-hosted relay can keep traffic on infrastructure you control). The veld-gateway only comes in for veld network share --web, which publishes a service on the open web for anyone with a browser, no Veld required.
The repo is the source of truth. Everything lives next to the code.
github.com/prosperity-solutions/veldSource, issues, releasesREADMEInstall, quick start, CLI reference, architecturedocs/configuration.mdFull veld.json specificationdocs/gateway.mdDeploying the public web gatewayschema/v3/veld.schema.jsonMachine-readable JSON Schema for veld.jsonllms-full.txtComplete docs in a single request, for LLMsveld is mostly glue. The hard parts are other people's brilliant work — thank you.
This whole project was vibe coded with it — every line, this page included. Without it, veld wouldn't exist.
HTTPS termination, reverse proxy, and an internal CA that makes local TLS just work.
QUIC peer-to-peer with NAT hole-punching and relay fallback. The whole sharing story.
The async runtime everything runs on.
The CLI argument parser behind every command and flag.
The HTTP framework powering the daemon UI and the gateway.
One embedded, WAL-mode database holds all of veld's state.
Memory-safe TLS for veld's own outbound connections.
Serialization for veld.json, state, and every --json payload.