worktree-devservers
v0.3.2
Published
Run multiple dev servers in git worktrees with automatic port allocation and reverse proxy routing via Caddy
Maintainers
Readme
worktree-devservers
Run multiple dev servers in git worktrees with automatic port allocation and reverse proxy routing. Each worktree gets its own <slug>.localhost URL on port 80.
Built for coding agents (Conductor, Claude Code, Cursor) that work in isolated worktrees, so multiple branches can run simultaneously without port conflicts.
How it works
- Finds free ports (checks both IPv4 and IPv6)
- Calls your start callback — you spawn whatever dev server you need
- Registers a Caddy reverse proxy route:
<slug>.localhost:80→localhost:<port> - Cleans up routes and stale entries on exit
Prerequisites
brew install caddy
caddy startInstall
bun add worktree-devserversUsage
CLI
The quickest way — no code needed:
dev-worktree --slug myapp -- bun run devThe allocated port is set as the PORT env var. You can also reference it explicitly with $PORT:
dev-worktree --slug myapp --port 4000 -- vite --port \$PORT| Flag | Default | Description |
|------|---------|-------------|
| --slug | (required) | Subdomain name |
| --port | 3000 | Starting port to search from |
Programmatic API
For more control, import and call startWorktree directly:
import { startWorktree } from "worktree-devservers";
const slug = process.env.WORKTREE_SLUG;
if (!slug) {
console.error("WORKTREE_SLUG is required");
process.exit(1);
}
startWorktree(slug, async (ctx) => {
const port = await ctx.findFreePort(3000);
const child = Bun.spawn(["bun", "run", "dev"], {
env: { ...process.env, PORT: String(port) },
stdio: ["inherit", "inherit", "inherit"],
});
return { port, process: child };
});Either way, access your dev server at http://<slug>.localhost.
API
startWorktree(slug, startFn, options?)
| Parameter | Type | Description |
|-----------|------|-------------|
| slug | string | Worktree identifier, used as the subdomain (<slug>.localhost) |
| startFn | (ctx: WorktreeContext) => Promise<WorktreeHandle> | Callback to start your dev server |
| options | WorktreeOptions | Optional configuration |
WorktreeContext
| Property | Type | Description |
|----------|------|-------------|
| slug | string | The worktree slug |
| findFreePort(start) | (start: number) => Promise<number> | Find next free port from start. Tracks allocations internally. |
WorktreeHandle
| Property | Type | Description |
|----------|------|-------------|
| port | number | Port Caddy should route to |
| process | Subprocess | Child process for lifecycle management |
WorktreeOptions
| Option | Default | Description |
|--------|---------|-------------|
| caddyAdmin | http://localhost:2019 | Caddy admin API URL |
| serverId | worktree-devservers | Caddy server block ID |
| listenPort | 80 | Port Caddy listens on |
License
MIT
