More apps from usSnipora

Guide

Dev servers in git worktrees: ports and leftovers

Worktrees let you, or three coding agents, work on several branches at once. Then two of them start a dev server on port 3000, and after you remove a worktree its server is still running.

By Anmol Sethi · Updated

In short

A worktree separates files, not ports, so give each one its own port (vite --port 5174 --strictPort). Before git worktree remove, stop the servers running from that folder; once a folder is gone, a server still listening from it is a leftover you can find with lsof.

1. Give each worktree its own port

Each worktree is a full checkout with the same config, so every copy asks for the same port. Vite quietly moves to the next free port, which makes it easy to open the wrong branch; Next.js, Rails and most others just fail with “address already in use”.

Pass the port when you start the server, and make Vite fail instead of moving:

npx vite --port 5174 --strictPort
PORT=3001 npm run dev        # Next.js, Express and most Node servers
bin/rails server -p 3001

To stop picking numbers by hand, derive the port from the branch, so the same branch always gets the same port:

PORT=$((3100 + $(git branch --show-current | cksum | cut -d' ' -f1) % 900)) npm run dev

For Vite, pass it on: npx vite --port $PORT --strictPort. Vite doesn’t read PORT on its own.

Rather click than type? Portlivo shows every port with its project and frees it in one click. Try it free for 7 days →

2. Stop a worktree’s servers before removing it

git worktree remove deletes the folder but leaves running processes alone. This prints the PID of every process whose working folder is inside the worktree, so you can stop them first:

dir=$(cd ../shop-fix && pwd -P)
lsof -a -d cwd -Fpn | awk -v d="$dir" '/^p/{p=substr($0,2)} /^n/{n=substr($0,2); if (n==d || index(n, d"/")==1) print p}'

Check what they are with ps -p <PID>, stop them with kill <PID>, then remove the worktree.

pwd -P matters: lsof reports real paths, so a folder under a symlink such as /tmp wouldn’t match otherwise.

3. Find servers whose worktree is already gone

Coding agents create and delete worktrees on their own, so the folder is often gone before you notice the server. A listening process whose working folder no longer exists is a leftover:

for pid in $(lsof -tiTCP -sTCP:LISTEN | sort -u); do
  cwd=$(lsof -a -p "$pid" -d cwd -Fn | sed -n 's/^n//p')
  [ -n "$cwd" ] && [ ! -d "$cwd" ] && echo "$pid $cwd"
done
61504 /Users/you/code/shop-fix

The one-click way: Portlivo

Portlivo shows the branch on every row and keeps worktrees of the same repo next to each other, so shop on main and shop on fix are easy to tell apart. Servers whose folder is gone get their own Leftover section with Stop All, which stops only those. Agents can do the same through Portlivo’s MCP server, and servers Claude Code or Codex started are marked too: see AI agent servers.

Questions people ask

Do git worktrees share ports?
Ports belong to your Mac, not to a folder, so every worktree competes for the same ones. Give each worktree its own port with --port or PORT=, or derive it from the branch name.
Does git worktree remove stop the dev server?
No. It deletes the folder and leaves processes running. Stop the servers running from the worktree first, or find them afterwards as listeners whose folder no longer exists.
Why did Vite start on 5174 instead of 5173?
Another worktree’s server already had 5173, so Vite moved to the next free port. Add --strictPort to get an error instead.

Try Portlivo free for 7 days. Every feature, no account.

Download for Mac

Still have a question?

Write to us — a real developer reads every email and replies personally.

support@portlivo.com