tarjan
Terraform / Aspire — but for your local dev environment

Spin up a whole product's local dev environment in one command

Clone five repos, start Postgres, install deps, run the API, boot the web app and the mobile app, wire up the cloud bits. tarjan turns that checklist into tarjan up.

$ tarjan upsingle static binary

Without tarjan

  • · clone repo A, B, C, D…
  • · install .NET / Node / Docker by hand
  • · start the database, run migrations
  • · start each backend in the right order
  • · npm install, start the frontend, the app…
  • · add every folder to your editor

With tarjan

$ tarjan up
✓ tools checked
✓ repos cloned → fresh workspace
✓ VS Code workspace generated
✓ postgres · migrate · api · web ready
  environment is up — Ctrl+C to stop

Everything a real product needs to run locally

Concurrent, dependency-ordered

Services start in parallel, each gated on its dependencies' health checks (TCP / HTTP / command). Cycles are rejected up front.

Self-healing

Crash isolation with per-service restart policies and backoff. One service dying never takes the environment down.

Live reload & hot restart

Edit the config → tarjan reload reconciles in place. Watch paths to restart a service on file change.

Local + cloud, together

Declare external cloud dependencies (probed, not started), tunnels as services, and pre-up hooks for auth and secrets.

Tool bootstrap

tarjan doctor --install installs the missing toolchain per-OS — opt-in, never behind your back.

Single binary

Written in Go: a single static binary for macOS, Linux and Windows. No runtime to install just to run the launcher.

Jobs & pipelines

kind: job runs to completion; dependents wait for exit 0. Chain them for migrations and ETL/ML steps.

Config in code

YAML by default, or Starlark (tarjan.star) when you want loops, conditionals and computed values — same single binary.

One declarative file

Repos to clone, tools to require, services to run — with dependencies, health checks and restart policies.

name: acme
repos:
  - { name: api, url: https://github.com/acme/api.git }
  - { name: web, url: https://github.com/acme/web.git }

services:
  - name: postgres
    docker: { image: postgres:16, ports: ["5432:5432"] }
    health: { tcp: "localhost:5432" }

  - name: migrate          # run-to-completion job
    kind: job
    command: "dotnet ef database update"
    dependsOn: [postgres]

  - name: api
    workdir: api
    command: "dotnet run"
    dependsOn: [migrate]
    health: { http: "http://localhost:5080/health" }
    restart: on-failure
    watch: { paths: ["src"] }

  - name: web
    workdir: web
    command: "npm run dev"
    dependsOn: [api]

workspace: { vscode: true }

A command for every step of the loop

tarjan upclone, check tools, generate workspace, start everything
tarjan status --watchlive readiness of every service
tarjan uifull-screen dashboard with logs + restart/reload
tarjan restart apirestart one service in place
tarjan reloadreconcile a running env to the edited config
tarjan exec api -- npm testrun in a service's dir + environment
tarjan logs api -ffollow a service's captured logs
tarjan doctor --installinstall the missing toolchain

Bring the whole thing up.

Download a prebuilt binary, point a config at your repos, and run tarjan up.