Fast git worktree manager for humans and AI agents.
Create, navigate, and clean up worktrees without the ceremony. wt handles path resolution, node_modules symlinking, and lifecycle hooks so you can get to work in seconds.
$ wt list
Branch Path Status
* main /home/you/project clean
feat-auth /home/you/project/.worktrees/feat-auth dirty (3 files)
fix-typo /home/you/project/.worktrees/fix-typo clean
curl -fsSL https://raw.githubusercontent.com/Junnyyy/wt/main/install.sh | bashRequires Bun.
git clone https://github.com/Junnyyy/wt.git
cd wt
bun installbun run linkbun run install:globalBoth methods install wt to ~/.local/bin/. Make sure it's in your PATH:
# Add to ~/.zshrc or ~/.bashrc if not already present
export PATH="$HOME/.local/bin:$PATH"bun run uninstallOr manually: rm ~/.local/bin/wt
wt cd prints a path but can't change your shell's directory directly. Add the shell integration to fix this:
wt shell-init >> ~/.zshrc && source ~/.zshrcOr inspect the function first and add it manually:
wt() {
if [ "$1" = "cd" ]; then
local dir
dir=$(command wt cd "$2" 2>/dev/null)
if [ -n "$dir" ]; then
cd "$dir"
else
command wt cd "$2"
fi
elif [ $# -eq 0 ]; then
local dir
dir=$(command wt)
if [ -n "$dir" ] && [ -d "$dir" ]; then
cd "$dir"
fi
else
command wt "$@"
fi
}With shell integration, wt cd feat-auth changes your working directory, and bare wt lets you navigate interactively.
wt add feat-auth # new branch off HEAD
wt add feat-auth --base main # new branch off mainCreates the worktree at .worktrees/feat-auth, symlinks node_modules and .env files from the main worktree, and runs any configured post-create hook.
wt list # or: wt lsShows all worktrees with branch name, path, and clean/dirty status.
cd $(wt cd feat-auth)With shell integration, just run wt cd feat-auth directly.
wt cd outputs only the path -- designed for shell integration and scripts.
wt rm feat-auth # fails if worktree has uncommitted changes
wt rm feat-auth -f # force removewt pruneCleans up metadata for worktrees whose directories were deleted manually.
wtWhen run with no arguments in a terminal, launches an interactive TUI:
- j/k or arrow keys to navigate
- Enter to navigate to the selected worktree
- d to remove a worktree (with confirmation)
- q to quit
When piped or in a non-TTY context, falls back to wt list.
Create a .wt.toml in your repo root to customize behavior. All settings are optional -- sensible defaults apply without it.
[symlinks]
# Files/directories to symlink from main worktree into new worktrees
patterns = ["node_modules", ".env", ".env.local"]
# Remove specific patterns from the list above (or from defaults)
# exclude = ["node_modules"]
[worktree]
# Directory for worktrees, relative to repo root
dir = ".worktrees"
[hooks]
# Shell command to run after creating a worktree
post_create = "bun install"
# Shell command to run before removing a worktree
pre_remove = ""See .wt.toml.example for a copy-paste starting point.
| Setting | Default |
|---|---|
| Symlinked patterns | node_modules, .env, .env.local |
| Excluded patterns | none |
| Worktree directory | .worktrees/ |
| Post-create hook | none |
| Pre-remove hook | none |
To keep the defaults but skip node_modules symlinking:
[symlinks]
exclude = ["node_modules"]Every command is non-interactive and outputs clean text suitable for scripting:
# Get worktree path for a branch
path=$(wt cd feat-auth)
# Create a worktree
wt add my-task
# Force remove without prompts
wt rm my-task -f- Non-TTY mode automatically uses plain list output (no TUI)
- All destructive operations use
--forceflag instead of interactive prompts - Exit codes:
0success, non-zero on error
Built with Bun, Effect TS, @effect/cli, and Ink.
ProcessService Bun.spawn wrapper
|
+-- GitWorktreeService git worktree list/add/remove/prune
+-- SymlinkService symlink creation and cleanup
+-- ConfigService .wt.toml loading with defaults
Services use Effect's dependency injection (Effect.Service + Layer). Errors are type-safe tagged unions (Data.TaggedError). The CLI is declarative via @effect/cli with auto-generated help and shell completions (wt --completions zsh).
bun install
bun run link # install as source symlink (edits take effect immediately)
bun run dev -- --help # run directly without installing
bun run build # compile standalone binary
bun run typecheck # type checkRequires the GitHub CLI (gh).
bun run release patch # 0.1.0 -> 0.1.1
bun run release minor # 0.1.0 -> 0.2.0
bun run release major # 0.1.0 -> 1.0.0This bumps package.json version, cross-compiles darwin arm64 and x64 binaries, commits, tags, pushes, and creates a GitHub Release with both binaries attached.
MIT