The pain of context switching
You are deep in a feature branch. Three files open, a mental model of the data flow loaded into your head, tests half-written. Then a critical bug report comes in. Something is broken in production.
The traditional workflow: stash your changes, switch branches, lose your mental context, fix the bug, commit, switch back, pop your stash, and hope that the stash applies cleanly and your mental model reassembles itself. More often than not, you spend twenty minutes getting back to where you were before the interruption.
Git worktrees solve this at the primitive level. Instead of switching branches in a single directory, you create a second working directory that points to a different branch of the same repository. Two branches, two directories, zero stashing. Your feature work stays exactly where you left it.
The problem is that worktrees are easy to create and painful to configure — especially in a monorepo.
Why worktrees are hard in monorepos
A Turborepo monorepo with pnpm workspaces adds layers of complexity that a simple git worktree add does not handle:
- Shared packages need building. The product app depends on compiled output from shared packages (
@nextsaasai/ui,@nextsaasai/utils,@nextsaasai/blog). A fresh worktree has nodist/directories — nothing compiles until you run the build pipeline. - Multiple environment files. The monorepo requires
.env.localfiles at three levels: repository root,apps/boilerplate/, andapps/marketing/. Missing any one of them means missing environment variables at runtime. - Port conflicts. Two Next.js dev servers cannot bind to the same port. Every worktree needs its own port configuration — but Next.js does not read
PORTfrom.env.local. The Commander.js CLI parser runs before@next/envloads environment variables. - Dev script patching. The only reliable way to set the port is the
--portCLI flag, which means every worktree needs itspackage.jsondev scripts patched with the correct port number. - Cleanup complexity.
git worktree removedoes not clean up untracked files like.turbo/daemon/that Turborepo creates. Leftover directories cause errors when creating future worktrees with the same name.
Any one of these issues is solvable in five minutes. All of them together, every time you want a parallel workspace, add up to thirty minutes of manual configuration that defeats the purpose of worktrees entirely.
The automation we built
The nextsaas.ai worktree command handles the complete lifecycle — creation, configuration, and cleanup — in a single step:
- Branch detection. Automatically identifies the parent branch for the worktree, defaulting to the current branch or allowing explicit specification.
- Directory creation. Creates the worktree in a predictable location relative to the main repository, with a naming convention that makes finding worktrees easy.
- Port assignment. Calculates unique ports based on the worktree's position (base port + offset), then patches
apps/boilerplate/package.jsonandapps/marketing/package.jsonwith the correct--portflags. - Environment setup. Copies all
.env.localfiles from the main repository to the worktree, adjusting port references in each file. - Dependency installation. Runs
pnpm installin the worktree to ensure the lockfile is respected. - Package building. Runs
pnpm buildfor shared packages so that application imports resolve immediately. - Git cleanup flags. Marks the patched
package.jsonfiles with--skip-worktreeso they do not appear as modified ingit status.
Removal is equally automated. The cleanup command runs git worktree remove, then follows with rm -rf on the directory to eliminate untracked files that Git's worktree removal intentionally leaves behind.
AI coding in parallel
The real motivation behind this automation was not traditional developer workflow — it was AI-assisted development.
Running multiple AI coding sessions against the same working directory creates a fundamental problem: write conflicts. Two sessions editing overlapping files will corrupt each other's work. This is not a theoretical risk — it happens the moment both sessions touch a shared utility, a config file, or a test suite. The more sessions you run in parallel, the worse the conflicts get.
Worktrees eliminate this entirely. Each AI coding session gets its own directory, its own dev server, its own Git state. There is no possibility of write conflicts because each session operates on a physically separate copy of the codebase. A refactor in the shared UI package can run in one worktree while a new API endpoint develops in another — same repository, same Git history, complete isolation.
The workflow benefit compounds from there. You spin up a second workspace in under a minute, and the feature session continues undisturbed while the hotfix session operates independently. When the fix ships, you remove the worktree and resume exactly where you left it. As a bonus, each session's accumulated context — the files it has read, the patterns it has learned, the approaches already tried — stays intact rather than being lost to a branch switch or stash cycle.
Transferable patterns
The specific automation we built is tailored to our Turborepo + pnpm monorepo. But the patterns transfer to any monorepo setup:
Worktree automation must handle everything a fresh clone would handle — environment files, port configuration, dependency installation, and package builds. If you would not hand someone a bare git worktree add directory and tell them "just run npm start," then your worktree tooling has gaps.
The --skip-worktree trick for patched files is universally useful. Any file that needs per-worktree modifications (port configs, environment overrides) should be invisible to git status so developers and CI tools see a clean working tree.