Make git worktrees actually usable.
runtree is a local-first CLI that lets you run multiple branches of the same project side by side without fighting your local setup.
Git worktrees are powerful. In practice, they are annoying:
- ports collide
- run commands break
- editor configs get weird
- logs get mixed up
- opening the right branch in the right browser tab is manual every time
runtree fixes that.
You install it once in a project, it scans your worktrees, asks how to run the app, remembers your editor, and gives you a clean workflow:
runtree up main
runtree up auth-refactor
runtree web auth-refactor
runtree code auth-refactor
runtree logs auth-refactorEach worktree gets:
- its own port
- its own runtime
- its own logs
- its own browser entrypoint
- its own editor entrypoint
So you can actually work in parallel:
- one branch for a refactor
- one branch for a fix
- one branch being handled by an AI agent
- one branch being reviewed locally
No containers. No preview deployment. No manual local orchestration.
runtree is especially useful if you:
- dream about using Git worktrees without hating your local setup
- need multiple branches running at the same time
- delegate work to Codex, Cursor, Claude Code, or other coding agents
- want faster PM and QA feedback without waiting for preview environments
Today, runtree focuses on local orchestration.
Soon, runtree expose will make a local branch shareable through a stable public URL for review and QA.
Install the latest release:
curl -fsSL https://raw.githubusercontent.com/EmilienDreyfus/runtree/main/install.sh | shInstall a specific version:
curl -fsSL https://raw.githubusercontent.com/EmilienDreyfus/runtree/main/install.sh | sh -s -- --version v0.1.0Install into a custom directory:
curl -fsSL https://raw.githubusercontent.com/EmilienDreyfus/runtree/main/install.sh | sh -s -- --install-dir /usr/local/binRequirements:
- macOS or Linux
gitcurl- a runnable application command that accepts a
{port}placeholder
Verify the install:
runtree versionModern development is no longer:
1 developer = 1 branch = 1 running app
It is increasingly:
1 developer = multiple branches = multiple agents = multiple running instances
That is where the default local tooling falls apart.
runtree is built for the moment where:
- you launch one agent on branch A
- you work yourself on branch B
- you want both apps running at the same time
- you do not want to waste time reconfiguring ports, terminals, editors, and logs
It works just as well for:
- a monolith with several parallel branches
- a repo with many long-lived feature worktrees
- a local stack where multiple services or libraries need to be launched independently
Initialize runtree in an existing Git repository:
runtree init \
--name newProject \
--run-command "npm run dev -- --port {port}"List available instances and import current worktrees:
runtree lsWhen runtree ls imports a worktree, it detects ignored top-level runtime files
such as .env and .env.local from the main worktree. If they are missing from
the imported worktree, runtree can symlink or copy them during import.
Start an instance:
runtree up mainStart every visible instance:
runtree start allRun a one-off command in an instance worktree:
runtree run main -- npm install
runtree run main -- poetry run python manage.py migrateOpen it in the browser:
runtree web mainOpen its worktree in your preferred editor:
runtree code mainFollow logs:
runtree logs main --followStop the runtime:
runtree down mainWithout runtree, Git worktrees are technically available but awkward in practice.
With runtree:
runtree up <instance>starts the right branch on the right portruntree start allstarts every visible instanceruntree web <instance>opens the right browser targetruntree code <instance>opens the right worktree in your editorruntree logs <instance>gives you the logs for that branch only
That is the real value: making parallel local development usable, not just theoretically possible.
For each imported worktree, runtree tracks:
- a stable instance name
- an allocated local port
- runtime status and PID
- a dedicated log file
- a browser URL template
- an editor entrypoint
Persistent local state lives under ~/.runtree/.
Core commands:
runtree initruntree lsruntree up <instance|all>runtree run <instance> -- <command> [args...]runtree down <instance|all>runtree restart <instance|all>runtree logs <instance>runtree web <instance>runtree code <instance>runtree pruneruntree editorruntree version
Version shortcuts:
runtree versionruntree --version
Re-run the installer:
curl -fsSL https://raw.githubusercontent.com/EmilienDreyfus/runtree/main/install.sh | shOr pin a newer tag explicitly:
curl -fsSL https://raw.githubusercontent.com/EmilienDreyfus/runtree/main/install.sh | sh -s -- --version v0.1.0If you used the default location:
rm -f ~/.local/bin/runtreeruntree keeps local state in ~/.runtree/. Remove it separately only if you want to delete project metadata and logs.
Install from source with Go:
go install github.com/EmilienDreyfus/runtree/cmd/runtree@latestOr build locally from a clone:
mkdir -p dist && go build -o dist/runtree ./cmd/runtreeRun the test suite:
go test ./...Releases are published on GitHub Releases.
Each release ships:
darwin/amd64darwin/arm64linux/amd64linux/arm64- SHA-256 checksums
Planned, not available yet:
runtree expose- stable public URLs for shared previews
- managed sharing infrastructure around
expose
The future expose capability is the natural next step:
- run a branch locally
- share it instantly with a PM or teammate
- avoid waiting for a feature environment or preview deployment
Stable public URLs and the managed infrastructure behind expose are intended to be offered as a service outside the scope of this public repository.
External contributions are welcome, but this repository is maintainer-reviewed and CLA-gated.
Before opening a pull request:
- read CONTRIBUTING.md
- read CLA.md
- confirm the PR checklist
This repository is source-available under Elastic License 2.0.
In practice:
- you can use
runtreelocally, including inside your company - you can modify it and redistribute it under the license terms
- you cannot provide
runtreeas a competing hosted or managed service
