Self-hosted orchestrator for Claude CodeRun Claude Code in parallel
on your own infrastructure.
docker run -d --name spwn \ -p 127.0.0.1:4317:4317 \ -v spwn-home:/home/spwn \ ghcr.io/spwn-gg/spwnThen open localhost:4317. Your one-time setup link is in the container logs. Other ways to install →
The problem
Parallel is easy now. Landing is the hard part.
- Ten sessions, one reviewer. You become the bottleneck, and you can’t tell which session is waiting on you.
- Worktrees isolate files, not services. A fresh worktree has no ports of its own, no database and no
.env. - Branches collide at merge time. Every conflict between two agents’ work lands on you.
Where spwn fits
Claude Code runs unmodified. spwn runs everything around it, on your infrastructure.
Section titled “Claude Code runs unmodified. spwn runs everything around it, on your infrastructure.”01 · Environments
A container or pod for every session
Section titled “A container or pod for every session”Run spwn on your laptop, a server or a Kubernetes cluster. A hook reports an exec prefix, and from then on the agent, every shell and the editor in that session run inside their own container, pod or remote host, with their own ports and services. spwn itself knows nothing about Docker or Kubernetes: the hook is a shell script you own.
name="spwn-$SPWN_TERMINAL_ID"docker run -d --name "$name" \ -v "$SPWN_WORKTREE:$SPWN_WORKTREE" \ -w "$SPWN_WORKTREE" my-dev-env sleep infinity
# Every pane in this session now runs inside itecho "::spwn:set:: exec=docker exec -it $name"pod="spwn-$SPWN_TERMINAL_ID"# A pod with the worktree mounted at the same pathkubectl apply -f session-pod.yamlkubectl wait --for=condition=Ready "pod/$pod" --timeout=120s
# Every pane in this session now runs inside itecho "::spwn:set:: exec=kubectl exec -it -c session $pod --"02 · Merging
Run five attempts. Land the winner. Keep main green.
Section titled “Run five attempts. Land the winner. Keep main green.”Fork any session at any turn, and the conversation and the code branch together. Compare the attempts lane by lane. Press Land and the session joins a merge queue: one at a time, synced from the real base, optionally checked on the merged tree, then merged. If a sync conflicts, the conflict goes back to the agent that wrote the code, and everything queued behind it keeps landing. Prefer review? Open a GitHub pull request in one click.
spwn calls this queue the land order.
03 · Automation & cost
Script your sessions. Know what every branch cost.
Section titled “Script your sessions. Know what every branch cost.”Workflows and schedules. JS or TS scripts in .spwn/workflows/ start sessions, prompt them, wait for the reply, and merge the result or open a PR. Schedule read-only prompts daily or weekly; missed runs catch up on start.
Cost in git. Each session writes its spend into a doc committed on its own branch, recomputed every turn and priced by model. Forks record inherited and own tokens separately, so a family of attempts adds up exactly. CI reads it straight from git.
export default async function main(spwn) { const issues = await spwn.github.rest( "GET", "/repos/acme/shop/issues?labels=bug"); for (const issue of issues) { const key = `issue-${issue.number}`; if (await spwn.sessions.find(key)) continue; const s = await spwn.sessions.create({ key, title: issue.title, prompt: `Reproduce and fix:\n\n${issue.body}`, }); await s.waitForTurn(); }}[cost]model = "claude-opus-5"ownUsd = 3.1077 # this branch's shareusd = 9.412 # the whole conversation
[cost.inherited] # copied from the parent, frozenrequests = 142# …
[cost.own] # first spent here: sum thisrequests = 70# …Why not something else
How spwn compares
spwn isn’t a replacement for Claude Code. It’s where you run many of them.
| spwn | Claude Code on its own | Desktop orchestrator apps | Vendor-cloud agents | tmux + worktrees you script | |
|---|---|---|---|---|---|
| Runs on | Your laptop, server or cluster | Your laptop | Your laptop | The vendor’s machines | Wherever you script it |
| Reached from | Any browser | That machine | That machine | The vendor’s app | SSH |
| A container or pod per session | Yes, set by your hooks | No, worktrees | Mostly worktrees | A vendor VM | If you build it |
| Merge queue that returns conflicts to the agent | Yes | No | No | No | If you build it |
| Cost per branch, in git | Yes | No, per session | No | No | No |
Your own claude and login, unmodified |
Yes | Yes | Varies | No, vendor-managed | Yes |
| Choose it when | Agents should run on infrastructure you control | One laptop, a few sessions | You want a native app on one machine | You don’t want to run anything | You like maintaining the glue |
Categories, not products: tools in each column differ and change quickly. Last reviewed October 2026. Using Claude Code on your laptop today? Keep it for focused work, and send the long-running and parallel work to spwn.
Security and data flow
Your code, your login, your network
- No proxy. Each session runs the unmodified
claudeCLI, which calls Anthropic directly. spwn isn’t in that path. It reads the transcript files Claude Code writes to disk, on the same machine, to show the conversation and count cost. - Your own Claude login. You sign in by running
claudein a terminal spwn opens. The CLI keeps its own credentials. What spwn stores itself is its own account sign-in and the GitHub token you give it, in its data folder on that machine. - Runs where you run it. Repos, worktrees, transcripts and cost docs stay on your machine or cluster. Bound to localhost it asks for nothing; bound wider it requires an account, and it can sit behind your reverse proxy.
An account on a spwn is a shell on the machine it runs on, as spwn’s user. Give one only to people you’d give that shell. Remote access →
Also in the box
The rest of the workbench
Section titled “The rest of the workbench”- The session inboxEvery session in one list, sorted by what needs you. Answer blocked prompts in place. spwn calls it the Fleet.
- Pull requestsOpen, track and merge GitHub PRs from the session that wrote them.
- Browser editorVS Code on the session's worktree, beside the agent, inside its environment.
- Scheduled tasksRun a read-only prompt daily or weekly. Missed runs are caught up on start.
Install
Up and running in one command
Section titled “Up and running in one command”docker run -d --name spwn \ -p 127.0.0.1:4317:4317 \ -v spwn-home:/home/spwn \ ghcr.io/spwn-gg/spwn- Open localhost:4317.
- Use the one-time setup link from the logs:
docker logs spwn. - Sign in to Claude in the terminal spwn opens.
- Add a GitHub token if you want private repos and pull requests.
- Add your first repo and start a session.
FAQ
Questions people ask first
Does it work with my Claude plan?
spwn runs the claude CLI you have signed in to, however you signed in: a Claude subscription or an API key. Sessions are the interactive CLI in a terminal. Scheduled tasks and a workflow’s agents.run call it headless. Whether your plan covers a given use is set by Anthropic’s terms, so check them for your plan.
Does spwn see my code or prompts?
Only on your own machine. spwn manages the worktrees and reads the transcripts Claude Code writes to disk, which is how it shows the conversation and counts cost. The agent’s API traffic goes straight from the CLI to Anthropic.
Does it support Codex, Gemini or other agents?
spwn is built for Claude Code. Definitions for Codex and Gemini ship with it but are marked experimental: they run, without the transcript, rewind and fork-from-a-turn features.
How is this different from Claude Code’s own worktrees?
A worktree per session is the starting point, not the product. spwn adds what happens around it: a container or pod per session, a merge queue that hands conflicts back to the agent, cost per branch, hooks, workflows, and a server you reach from a browser.
Do I need Kubernetes?
No. spwn runs on a laptop with sessions on the host, or with a Docker container per session. Kubernetes is one more place it can run.
What happens when two sessions conflict?
spwn shows the overlap before you merge. In the merge queue, a session that conflicts when it syncs from the base is handed back to its own agent with the conflict, and the sessions queued behind it keep landing. If the agent can’t resolve it after two tries, the session is taken out of the queue with the reason.
Windows? Teams? Single sign-on?
spwn runs on macOS and Linux. Out of the box it has one local account. Sign-in through a reverse proxy or OIDC is available in builds made with the enterprise feature. Everyone who signs in gets a shell as the same user, sharing its Claude login and GitHub token, so accounts say who someone is, not what they may do.