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 veldWith veld
localhost:3000, :3001, :8080https://frontend.dev.myproject.localhost
Manual mkcert + reverse proxyAutomatic TLS, auto-trusted
"Start the API before the frontend"Dependency graph, health checks
Describe UI issues in chat to the agentBuilt-in feedback overlay: humans annotate, agents receive structured feedback

Core concepts

Working Directory
Set cwd at the node or variant level to run commands from a subdirectory. In monorepos, this replaces repetitive cd <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_server gets a real HTTPS URL via Caddy. The CA is trusted in your system keychain during veld 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 --json for machine-readable output. Designed for CI pipelines and AI agent consumption.

Quick start

  1. Create a veld.json in 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 }
            }
          }
        }
      }
    }
  2. Start the environment:
    veld start backend:local --name dev
  3. Check status and URLs:
    veld status --name dev
    veld urls --name dev
  4. Stop:
    veld stop --name dev

CLI reference

CommandDescription
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"

View the full JSON Schema


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}"
          }
        }
      }
    }
  }
}