DevTools Workflow 8 min read

VS Code Git Worktrees + Claude Code: Parallel Development with Lifecycle Hooks

Hoang Dang Tan Phat (Kane)

Hoang Dang Tan Phat (Kane)

Feb 4, 2026

Git worktrees let you check out multiple branches simultaneously in separate directories. Combined with the VS Code Git Worktrees extension and its .worktree.yml lifecycle hooks, you can automate the entire setup — including spawning tmux sessions for Claude Code — every time you create, switch, or remove a worktree.

Why Git Worktrees?

Traditional branching requires stashing or committing before switching. Worktrees eliminate this friction:

# Instead of this painful dance:
git stash
git checkout feature-b
# work on feature-b...
git checkout feature-a
git stash pop

# You get parallel directories:
~/projects/myapp/          # main branch
~/projects/myapp-feature-a/ # feature-a branch
~/projects/myapp-feature-b/ # feature-b branch

Each worktree is an independent working directory with its own branch. You can run different tasks, different servers, different Claude Code sessions — all at the same time.

The VS Code Git Worktrees Extension

The Git Worktrees extension wraps git worktree commands into an interactive VS Code UI. I’ve forked and updated it to add .worktree.yml lifecycle hooks support — you can install the .vsix directly from the fork. Open the command palette (Ctrl+Shift+P) and search for Git Worktree::

  • Add — Create a new worktree from a remote branch
  • List — View all worktrees and switch between them (opens a new VS Code window)
  • Remove — Delete a worktree (with force-delete for dirty trees)

No more terminal juggling. But the real power comes from lifecycle hooks.

.worktree.yml — Lifecycle Hooks

Drop a .worktree.yml file in your repository root. The extension reads it and executes commands automatically during worktree operations.

Supported Events

EventTriggerFeatures
addAfter creating a new worktreecopy files + run commands
switchWhen switching to a worktreeRun commands
removeBefore deleting a worktreeRun commands

Available Variables

Use these in any command string:

VariableResolves ToExample
${userHome}User home directory/home/phathdt
${workspaceFolder}Full worktree path/home/phathdt/projects/myapp-feat-x
${workspaceFolderBasename}Worktree folder namemyapp-feat-x
${repositoryName}Origin repo namemyapp

Full Example: .worktree.yml

# .worktree.yml - Lifecycle hooks for git worktree operations

add:
  copy:
    - .env
    - .env.local
  commands:
    - yarn install
    - yarn db:generate
    - tmux has-session -t ${repositoryName} 2>/dev/null && tmux new-window -t ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder} || tmux new-session -d -s ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder}

switch:
  commands:
    - tmux has-session -t ${repositoryName} 2>/dev/null && tmux new-window -t ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder} || tmux new-session -d -s ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder}

remove:
  commands:
    - tmux kill-window -t ${repositoryName}:${workspaceFolderBasename} 2>/dev/null || true

Let’s break down what happens.

The Workflow in Action

1. Creating a Worktree (add)

When you run Git Worktree: Add from the command palette:

  1. Extension creates the worktree via git worktree add
  2. Copies .env and .env.local from the main repo to the new worktree — no manual setup
  3. Runs yarn install inside the new worktree
  4. Runs yarn db:generate for database schemas
  5. Creates or attaches a tmux session named after your repo, with a window named after the worktree folder

The tmux command is the key piece:

tmux has-session -t ${repositoryName} 2>/dev/null \
  && tmux new-window -t ${repositoryName} \
       -n ${workspaceFolderBasename} \
       -c ${workspaceFolder} \
  || tmux new-session -d \
       -s ${repositoryName} \
       -n ${workspaceFolderBasename} \
       -c ${workspaceFolder}

This checks if a tmux session named myapp exists. If yes, it adds a new window. If not, it creates a new session. Either way, the window’s working directory is the worktree path and the window is named after the branch.

2. Switching Worktrees (switch)

When you switch via Git Worktree: List, the same tmux command runs — ensuring you always have a terminal window ready at the right directory for the worktree you’re switching to.

3. Removing a Worktree (remove)

Before deletion, the corresponding tmux window is killed:

tmux kill-window -t ${repositoryName}:${workspaceFolderBasename} 2>/dev/null || true

The || true ensures the removal proceeds even if the tmux window was already closed.

Claude Code + Worktrees = Parallel AI Development

Here’s where it gets powerful. Each tmux window is an isolated terminal session. You can run Claude Code (claude) in each one independently:

tmux session: myapp
├── window: main         → claude (working on docs)
├── window: feat-auth    → claude (implementing auth)
└── window: fix-bug-123  → claude (debugging issue)

Each Claude Code instance has its own context, its own working directory, its own branch. No conflicts. No context switching. You review one window while Claude works in another.

Typical Parallel Workflow

  1. Open VS Code on your main branch
  2. Ctrl+Shift+PGit Worktree: Add → select origin/feature-auth → extension creates worktree, installs deps, copies .env, opens tmux window
  3. Repeat for origin/fix-bug-123
  4. Attach tmux: tmux attach -t myapp
  5. In each window: run claude to start a Claude Code session
  6. Switch between tmux windows with Ctrl+B then window number
  7. When done, Git Worktree: Remove cleans up the worktree and kills the tmux window

Project-Specific Customization

Adapt the add.commands to your stack:

# Node.js / pnpm project
add:
  copy:
    - .env
    - .env.local
  commands:
    - pnpm install
    - pnpm db:push
    - tmux has-session -t ${repositoryName} 2>/dev/null && tmux new-window -t ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder} || tmux new-session -d -s ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder}
# Go project
add:
  copy:
    - .env
  commands:
    - go mod download
    - tmux has-session -t ${repositoryName} 2>/dev/null && tmux new-window -t ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder} || tmux new-session -d -s ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder}
# Python project
add:
  copy:
    - .env
  commands:
    - python -m venv .venv
    - .venv/bin/pip install -r requirements.txt
    - tmux has-session -t ${repositoryName} 2>/dev/null && tmux new-window -t ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder} || tmux new-session -d -s ${repositoryName} -n ${workspaceFolderBasename} -c ${workspaceFolder}

Extension Settings Worth Knowing

Configure these in VS Code settings (Ctrl+,):

SettingDefaultWhat it does
vsCodeGitWorktrees.move.openNewVscodeWindowtrueOpens a new VS Code window when creating/switching worktrees
vsCodeGitWorktrees.worktrees.dir.pathnullCustom directory for all worktrees (supports variables)
vsCodeGitWorktrees.add.autoPushtrueAuto-push new worktree branch to remote
vsCodeGitWorktrees.add.autoPulltrueAuto-pull after creating worktree branch
vsCodeGitWorktrees.worktree.coloringfalseColor labels for worktree windows

A useful pattern for worktrees.dir.path:

${userHome}/worktrees/${repositoryName}

This keeps all worktrees organized under a single directory instead of scattering them as siblings of your main repo.

Key Details

  • Commands run sequentially in the worktree directory, not the source repo
  • Failed commands show a warning but don’t block the operation — your worktree still gets created/removed
  • Missing copy files are skipped with a warning, not an error
  • Git >= 2.34.1 is required
  • .worktree.yml goes in your repo root and can be committed to share with your team

Summary

The combination of git worktrees, VS Code Git Worktrees extension, .worktree.yml lifecycle hooks, and tmux creates an automated parallel development environment. Each worktree gets its own VS Code window, its own terminal, its own dependencies, and its own Claude Code session — all set up with a single command palette action.

No manual cd. No manual npm install. No manual tmux session management. Just branch, work, and clean up.

vscode git-worktree claude-code tmux developer-workflow productivity
Hoang Dang Tan Phat (Kane)

Hoang Dang Tan Phat (Kane)

Full-stack developer with 8+ years experience. Building scalable systems with Go, TypeScript, and React.