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 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 start --preset fullstack
# hand it to a colleague on the web — no Veld on their end:
veld 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 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 runs 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 config set. Kept per machine and shared across all your worktrees, so you answer it once, not once per checkout.
veld 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 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 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.
What you'll actually type. Every one speaks --json.
veld start NODE:VARIANT --name NStart an environmentveld start --preset NAME|KEYStart a preset — a saved selection of nodes (e.g. fullstack). Or just veld start and pick from the listveld 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 stop [--name N] [--all]Stop a running environmentveld restart [--name N]Restart an environmentveld status [--name N]Show run statusveld stats [--processes] [--history] [--cpu]Detailed CPU & memory — split by memory type and by subprocess, with historyveld urls [--name N]Show URLs for a runveld logs [-f] [-s TERM] [--run ID]View logs (follow, search, source filter — including past runs)veld graph / nodes / presets / runsInspect the config and the run historyveld lintCheck the config for problems — every one at once, exits non-zero in CIveld config --files / --why PWhich file defines which node, and where an effective value came fromveld config vars / set / unsetValues that differ per machine — answered once, shared across your worktreesveld settings [get / set / describe]Veld’s own preferences from the terminal — describe gives an agent the type, default and allowed valuesveld action NAMERun a node-defined action (e.g. open the DB in a GUI)veld share [RUN] [--web]Share a run over an encrypted P2P tunnel (or the open web)veld join TICKETJoin a shared env; the same URLs materialize locallyveld sharesList shares, joins, and pending requests with transport infoveld approve / deny REQGate who connects to your shareveld unshare / leaveStop hosting, or disconnect from a joined shareveld setup [privileged]One-time system setup (clean URLs need privileged; unprivileged is no-sudo)veld initCreate a new veld.json (veld reads veld.jsonc too)veld uiOpen the management dashboardveld feedback nextPull the next in-browser review comment (agent-facing)veld doctor / gcCheck extension status; clean up stale stateveld backup [now / restore]Copies of veld's own state database, and putting one backOne 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 setup privileged — sudo once, never again. Prefer no sudo at all? veld 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 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.
Every app veld serves gets an in-browser overlay. Review the running thing and hand comments straight to your agent — no copy-pasting screenshots into a chat.
/veld-launch-feedback-loop and hit enter — it parks on veld feedback next and waits for you.veld feedback next — element, selector, screenshot, and your words, in one call.Fun fact: this entire page was built and refined through exactly that loop.
For the nerds. A few small Rust binaries, one config file, and Caddy for HTTPS — that's the whole thing.
The CLI. Parses commands, orchestrates environments, resolves the dependency graph, displays output.
User-space daemon. 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, feedback, tokens — in one WAL-mode database. Versioned, migrates forward.
veld 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 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.