box
Safe, disposable dev environments for AI coding agents — powered by Docker and git.

Why box?
AI coding agents (Claude Code, Cursor, Copilot) are powerful — but letting them loose on your actual working tree is risky. Box gives them a safe, isolated sandbox where they can go wild without consequences.
- Your code stays safe — an independent clone is used, host files are never modified
- AI agents can experiment freely — commit, branch, rewrite, break things — your working tree is untouched
- Persistent sessions — exit and resume where you left off, files are preserved
- Named sessions — run multiple experiments in parallel
- Bring your own toolchain — works with any Docker image
Requirements
Install
Quick install
|
From crates.io
From source
Nix
Binary download
Pre-built binaries are available on the GitHub Releases page.
Quick Start
# Shortcut for `box create my-feature` — creates a new isolated session
Box must be run inside a git repository — it clones the current repo into the container.
For a zero-flags workflow, see Custom Image Setup below.
Custom Image Setup
The recommended way to use box: build your image once, set a couple of env vars, and never pass flags again.
1. Create a Dockerfile with your toolchain
Include whatever tools your workflow needs (languages, runtimes, CLI tools, etc.).
2. Build the image
3. Set environment variables
Add these to your .zshrc or .bashrc:
# your custom image
# any extra Docker flags you always want
# default command for new sessions
4. Done — just use box
With those env vars set, every session uses your custom image with zero flags:
# That's it. From now on:
# Each gets an isolated sandbox with your full toolchain.
Usage
)
|
Session manager
Running box with no arguments opens an interactive TUI:
NAME STATUS PROJECT IMAGE CREATED
New box...
> my-feature running /Users/you/projects/app alpine:latest 2026-02-07 12:00:00 UTC
test /Users/you/projects/other ubuntu:latest 2026-02-07 12:30:00 UTC
[Enter] Resume [d] Delete [q] Quit
- Enter on a session to resume it, or on "New box..." to create a new one
- d to delete the highlighted session (with confirmation)
- q / Esc to quit
Create a session
# Shortcut: just pass a name
# Equivalent explicit form
# Custom image with bash
# Extra Docker flags (env vars, volumes, network, etc.)
# Create in detached mode (background)
Resume a session
# Resume an existing session
# Resume in detached mode
# Detach without stopping: Ctrl+P, Ctrl+Q
Run a command in a session
# Run a command in a running session
# Open a shell in a running session
Stop and remove
# Stop a running session
# Remove a stopped session (container, workspace, and session data)
Options
box create
| Option | Description |
|---|---|
-d |
Run container in the background (detached) |
--image <image> |
Docker image to use (default: alpine:latest) |
--docker-args <args> |
Extra Docker flags (e.g. -e KEY=VALUE, -v /host:/container). Overrides $BOX_DOCKER_ARGS |
--no-ssh |
Disable SSH agent forwarding (enabled by default) |
-- cmd... |
Command to run in container (default: $BOX_DEFAULT_CMD if set) |
box resume
| Option | Description |
|---|---|
-d |
Resume in the background (detached) |
--docker-args <args> |
Extra Docker flags. Overrides $BOX_DOCKER_ARGS |
Environment Variables
These let you configure defaults so you can skip CLI flags entirely. Set them in your .zshrc or .bashrc and every box <name> invocation uses them automatically.
| Variable | Description |
|---|---|
BOX_DEFAULT_IMAGE |
Default Docker image for new sessions (default: alpine:latest) |
BOX_DOCKER_ARGS |
Default extra Docker flags, used when --docker-args is not provided |
BOX_DEFAULT_CMD |
Default command for new sessions, used when no -- cmd is provided |
# Set default Docker flags for all sessions
# Override with --docker-args for a specific session
Shell Completions
Add one of these to your shell config to enable tab completion for session names and subcommands:
# Zsh (~/.zshrc)
# Bash (~/.bashrc)
After reloading your shell, box [tab] will show available sessions and subcommands.
How It Works
On first run, git clone --local creates an independent copy of your repo in the workspace directory. The container gets a fully self-contained git repo — no special mounts or entrypoint scripts needed. Your host working directory is never modified.
- Independent clone — Each session gets its own complete git repo via
git clone --local - Persistent workspace — Files survive
exitandbox resume <name>picks up where you left off; cleaned up withbox remove - Any image, any user — Works with root and non-root container images
| Aspect | Protection |
|---|---|
| Host working tree | Never modified — workspace is an independent clone |
| Workspace | Bind-mounted from ~/.box/workspaces/<name>/, persists across stop/start |
| Session cleanup | box remove deletes container, workspace, and session data |
Design Decisions
Several git isolation strategies exist — here's why the alternatives fall short:
| Strategy | Problem |
|---|---|
| Bind-mount the host repo | No isolation at all; the agent modifies your actual files |
| git worktree | Shares the .git directory with the host; checkout, reset, and rebase can affect host branches and refs |
| Bare-git mount | Still shares state; branch creates/deletes in the container affect the host |
| Branch-only isolation | Nothing stops the agent from checking out other branches or running destructive git commands on shared refs |
Full copy (cp -r) |
Truly isolated but slow for large repos |
git clone --local wins because it's:
- Fully independent — the clone has its own
.git; nothing in the container can touch the host repo - Fast — hardlinks file objects on the same filesystem instead of copying
- Complete — full history, all branches, standard git repo
- Simple — no wrapper scripts or special entrypoints needed
Some tools (e.g. Claude Code's --sandbox) provide built-in Docker sandboxing. Box takes a different approach — using plain Docker directly — which unlocks:
- Your own toolchain — use any Docker image with the exact languages, runtimes, and tools you need
- Persistent sessions — exit and resume where you left off; files and state are preserved
- SSH agent forwarding —
git push/git pullwith your host SSH keys, out of the box - Full Docker control — custom network, volumes, env vars, and any other
docker runflags - Works with any agent — not tied to a specific tool; use Claude Code, Cursor, Copilot, or manual workflows
Plain Docker gives full control while box handles the isolation and lifecycle.
SSH Agent Forwarding
The problem: Docker containers can't normally access your host SSH keys. On macOS it's even harder — Docker runs in a VM, so Unix sockets can't cross the VM boundary.
What box does: Automatically forwards the host's SSH agent into the container. git push, git pull, and ssh all work with your existing keys — no key copying needed.
How it works per platform:
- macOS (Docker Desktop / OrbStack): Mounts the VM-bridged socket at
/run/host-services/ssh-auth.sock - Linux: Mounts
$SSH_AUTH_SOCKdirectly into the container
Box also re-points the cloned repo's origin remote to the real URL (not the local clone path), so git push origin works out of the box.
# Inside the container
# To disable SSH forwarding
Security Note
The --docker-args flag and BOX_DOCKER_ARGS environment variable pass arguments directly to docker run. This means flags like --privileged, --pid=host, or -v /:/host can weaken or bypass container sandboxing. Only use trusted values and be careful when sourcing BOX_DOCKER_ARGS from shared or automated environments.
Claude Code Integration
Box is the ideal companion for Claude Code. Run Claude Code inside a box session and let it make risky changes, experiment with branches, and run tests — all fully isolated from your host.
Run in the background with detach mode:
Everything the agent does stays inside the container. When you're done, delete the session and it's gone.
License
MIT