> ## Content Index
> Fetch the complete content index at: https://madewithlove.com/blog/llms.txt
> Use this file to discover other available public pages before exploring further.

# Worktrunk takes the friction out of Git worktrees
- URL: https://madewithlove.com/blog/worktrunk-takes-the-friction-out-of-git-worktrees/
- Published: 2026-10-07T16:47:40.000Z
- Updated: 2026-10-07T16:47:40.000Z
- Description: Git worktrees let you run agents in parallel, but every new worktree starts cold, fights over ports and leaves junk behind. Worktrunk wraps worktrees in a few simple commands and a hook system, so one config file gives the whole team warm, isolated environments that clean up after themselves.
- Author: Wouter Sioen
- Tags: Engineering, Tooling, Claude, Tutorials, AI, AI development

A while ago I wrote about how I [parallelise myself with Git worktrees](https://madewithlove.com/blog/parallelise-yourself-with-git-worktrees/). I still do. But after a few months of it, the friction started to add up. **Worktrees make parallel work possible. They don't make it pleasant.**

## The friction

Three things kept getting in the way.

**Every worktree starts cold.** The code is there, but the app won't run. No environment variables, no vendor files, nothing that's gitignored. It's like cloning a blank project and running the whole setup again.

**Ports collide.** Spin up a Docker stack in a second worktree and it tries to grab the same database port as the first one. You fix it by hand, or you let Claude fix it. Either way, it takes a while.

**Worktrees leave junk behind.** Remove a worktree and its containers and volumes stay. After a few weeks, you have a machine full of Docker containers nobody needs anymore.

None of these is a big deal on its own. But when you're [running several agents in parallel](https://madewithlove.com/blog/conductor-running-multiple-ai-coding-agents-in-parallel/), you hit all three many times a day.

## Worktrunk

[Worktrunk](https://worktrunk.dev/) is a small CLI that wraps [Git worktrees](https://git-scm.com/docs/git-worktree). There are other tools that do something similar, but this is the one we've been using on two projects, and it's been very useful.

First, it replaces the worktree commands you never remember with a few that make sense:

```
wt switch --create my-feature   # new branch and worktree in one go
wt list                         # everything you have open
wt merge                        # merge it and clean up
```

The real power is in the hooks. Worktrunk runs shell commands at points in the worktree lifecycle, such as after a worktree starts or before it's removed. You configure them in a single file committed to the repository, so **it works the same for everyone on the team**.

## The hooks we use

Here's a simplified version of our config. It's just a few lines of shell. Nothing fancy, easy to read and easy to tweak.

![A slide showing a post-start hook and a .worktreeinclude file](https://madewithlove.com/blog/content/images/2026/10/worktrunk-1-copy-what-git-ignores.png)

Copy what git ignores.

```
# .config/wt.toml
[[post-start]]
copy = "wt step copy-ignored"

[[post-start]]
port = "echo APP_PORT={{ branch | hash_port }} >> .env"

[pre-remove]
cleanup = "docker compose down --volumes"
```

**A warm start.** After a worktree is created, we copy over the gitignored files: the environment file, vendor directories, everything you'd otherwise rebuild. Copying takes milliseconds. Running a full dependency install and filling in an env template does not.

**A port per branch.** The `hash_port` filter turns the branch name into a port number, and we write that into the environment. The same branch always gets the same port. So every worktree has its own port and its own database, and you can tear it down and spin it up again later without thinking about it.

**A clean exit.** Before a worktree is removed, we bring the Docker stack down and delete its volumes. No more leftovers.

## What it looks like in practice

Create a worktree and everything is there. If it's a change that needs the app running, spin up the stack. If it's a small documentation fix, don't bother. List your worktrees whenever you lose track. Merge, and everything is cleaned up.

![One repository feeding three running worktrees](https://madewithlove.com/blog/content/images/2026/10/worktrunk-2-every-worktree-a-running-app.png)

Every worktree is a running app.

It's a small thing. But small friction compounds, especially when your [job has shifted to orchestrating](https://madewithlove.com/blog/out-with-multitasking-in-with-orchestrating/) instead of typing.

## TL;DR

If you use Git worktrees for parallel work, give Worktrunk a try. One config file in the repository, and every worktree starts warm, gets its own port and cleans up after itself.

Your disk will thank you.