veld
Open-source local development environment orchestrator. One command starts every service with real HTTPS URLs — no port numbers, no manual wiring. Works with monorepos, multi-repo setups, or any project directory.
Built for the agentic era
AI agents can start environments, inspect health, read logs, and receive human feedback — all through structured CLI output. Every command supports --json. The built-in feedback overlay lets humans annotate running UIs while agents receive structured results. veld is designed for human-agent collaboration from the ground up.
- License
- MIT
- Language
- Rust
- Platforms
- macOS (arm64/x64), Linux (x64/arm64)
- Source
- github.com/prosperity-solutions/veld
- Website
- veld.oss.life.li
Install
curl -fsSL https://veld.oss.life.li/get | bash
Agent Skills
Teach your coding agent how to use veld. Works with Claude Code, Cursor, Codex, Windsurf, and 40+ more.
npx skills add prosperity-solutions/veld
- veld-config
- Write and edit
veld.json— nodes, health checks, dependencies, URL templates, presets. The agent produces correct configuration without guessing. - veld-feedback
- Human-in-the-loop feedback workflow. The agent requests reviews via
veld feedback --wait, receives structured comments with element selectors and component traces, and iterates. - veld-usage
- CLI reference — start, stop, logs, status, and all other commands. The agent knows every flag and common pattern.
What it replaces
| Without veld | With veld |
|---|---|
| localhost:3000, :3001, :8080 | https://frontend.dev.myproject.localhost |
| Manual mkcert + reverse proxy | Automatic TLS, auto-trusted |
| "Start the API before the frontend" | Dependency graph, health checks |
| Describe UI issues in chat to the agent | Built-in feedback overlay: humans annotate, agents receive structured feedback |
Core concepts
- Working Directory
- Set
cwdat the node or variant level to run commands from a subdirectory. In monorepos, this replaces repetitivecd <dir> &&prefixes. Variant-level overrides node-level. - Dependency Graphs
- Declare which services depend on which. Veld resolves the graph, starts in topological order, parallelizes where possible, and tears down in reverse.
- HTTPS Everywhere
- Every
start_servergets a real HTTPS URL via Caddy. The CA is trusted in your system keychain duringveld setup— browsers accept certificates without warnings. - Health Checks
- Two-phase: TCP port check, then HTTP/port/command verification. Downstream services wait until dependencies are healthy.
{ "type": "http", "path": "/health", "timeout_seconds": 30 }- Named Runs
- Each environment gets a name (
--name dev). Run multiple environments side-by-side from different branches. Names appear in URLs:https://frontend.dev.myproject.localhost. - Feedback Overlay
- Built-in UI injected into running services. Click to annotate, screenshot, and share — no separate tools needed. The overlay also captures React and Vue component stack traces alongside CSS selectors, giving agents precise context about which component to modify.
- Structured Output
- Every command supports
--jsonfor machine-readable output. Designed for CI pipelines and AI agent consumption.
Quick start
- Create a
veld.jsonin your project root:{ "$schema": "https://veld.oss.life.li/schema/v1/veld.schema.json", "schemaVersion": "1", "name": "myproject", "url_template": "{service}.{run}.{project}.localhost", "nodes": { "backend": { "default_variant": "local", "variants": { "local": { "type": "start_server", "command": "npm run dev -- --port ${veld.port}", "health_check": { "type": "http", "path": "/health", "timeout_seconds": 30 } } } } } } - Start the environment:
veld start backend:local --name dev - Check status and URLs:
veld status --name dev veld urls --name dev - Stop:
veld stop --name dev
CLI reference
| Command | Description |
|---|---|
veld start [NODE:VARIANT...] --name <n> [-d] | Start an environment (-d for detached) |
veld stop [--name <n>] [--all] | Stop a running environment |
veld status [--name <n>] [--json] | Show run status |
veld urls [--name <n>] [--json] | Show URLs for a run |
veld logs [--name <n>] [--node <n>] [--lines <n>] [-f] [--since <d>] [--source <s>] [-s <term>] [-C <n>] | View logs (-f follow, -s search, -C context lines) |
veld feedback [--name <n>] [--wait] | Open feedback UI for a run |
All commands support --json for structured output.
Additional commands: restart, init, setup, gc, graph, nodes, presets, runs — see the README for the full reference.
Configuration reference
veld is configured with a veld.json file at your project root. It defines nodes (services or setup tasks), their variants, health checks, dependencies between them, URL templates for HTTPS routing, and presets for common combinations.
The full configuration schema is available as a JSON Schema — point your editor at it for autocompletion and validation:
"$schema": "https://veld.oss.life.li/schema/v1/veld.schema.json"
Architecture
Three binaries work together:
- veld (CLI)
- Parses commands, orchestrates environments, displays output. Communicates with the daemon via Unix socket.
- veld-helper (system or user daemon)
- Manages DNS entries and Caddy reverse-proxy routes via a minimal Unix socket API. Runs as a system daemon in privileged mode (ports 80/443, custom domains) or as a user process in unprivileged mode (port 18443, .localhost domains only).
- veld-daemon (user-space daemon)
- Monitors service health, runs garbage collection, broadcasts state updates, serves the feedback overlay.
- Caddy (reverse proxy)
- Handles HTTPS termination and reverse proxying. Its internal CA is trusted in the system keychain during setup.
Communication flow:
veld CLI → veld-daemon (health, state, feedback)
veld CLI → veld-helper (DNS, Caddy routes)
veld-helper → Caddy (route configuration)
Caddy → your services (reverse proxy with TLS)
Complete example
A typical full-stack setup. For the complete list of fields, types, and options, see the JSON Schema.
{
"$schema": "https://veld.oss.life.li/schema/v1/veld.schema.json",
"schemaVersion": "1",
"name": "myproject",
"url_template": "{service}.{run}.myproject.localhost",
"presets": {
"fullstack": ["database:docker", "backend:local", "frontend:local"],
"frontend-only": ["frontend:local"]
},
"nodes": {
"database": {
"default_variant": "docker",
"variants": {
"docker": {
"type": "start_server",
"command": "docker run --rm -p ${veld.port}:5432 postgres:16",
"health_check": { "type": "port", "timeout_seconds": 15 },
"outputs": {
"DATABASE_URL": "postgres://dev:dev@localhost:${veld.port}/app"
}
}
}
},
"backend": {
"default_variant": "local",
"variants": {
"local": {
"type": "start_server",
"command": "cargo run -- --port ${veld.port}",
"health_check": { "type": "http", "path": "/health" },
"depends_on": { "database": "docker" },
"env": {
"DATABASE_URL": "${nodes.database.DATABASE_URL}"
}
}
}
},
"frontend": {
"default_variant": "local",
"variants": {
"local": {
"type": "start_server",
"command": "npm run dev -- --port ${veld.port}",
"health_check": { "type": "http", "path": "/" },
"depends_on": { "backend": "local" },
"env": {
"API_URL": "${nodes.backend.url}"
}
}
}
}
}
}