Predictable ports and environment overlays for Git worktrees.
workslot lets every worktree of the same project run locally without fighting over localhost:3000, localhost:5432, localhost:6379, or any other fixed dev port.
It is a small standalone CLI. It does not require a server, database, SaaS account, MCP connection, or application code changes if your app already reads ports and URLs from environment variables.
Git worktrees are useful for parallel development:
git worktree add ../app-feature feature/payments
git worktree add ../app-bugfix bugfix/loginBut local dev servers usually expect the same ports:
frontend -> 3000
backend -> 7834
redis -> 6379
docs -> 8080
workslot assigns each worktree a stable slot and derives ports from that slot:
main worktree -> slot 0 -> frontend 3000, backend 7834
feature worktree -> slot 1 -> frontend 3001, backend 7835
bugfix worktree -> slot 2 -> frontend 3002, backend 7836
For now, build from source:
git clone https://github.com/mironovisa/workslot.git
cd workslot
go install .Later this can be distributed through Homebrew and GitHub Releases.
Inside your project:
workslot init
workslot claim
workslot run npm run devworkslot run starts your existing command with a generated environment overlay.
.workslot.json declares base ports and the env variables that should change per worktree:
{
"slotOffset": 1,
"maxSlots": 50,
"envFiles": [".env", ".env.local"],
"ports": {
"frontend": 3000,
"backend": 7834
},
"env": {
"PORT": "${ports.frontend}",
"BACKEND_PORT": "${ports.backend}",
"NEXT_PUBLIC_API_URL": "http://localhost:${ports.backend}"
}
}For slot 2, workslot writes .env.worktree:
# Generated by workslot. Do not put secrets here.
WORKSLOT_SLOT=2
WORKSLOT_PORT_BACKEND=7836
WORKSLOT_PORT_FRONTEND=3002
BACKEND_PORT=7836
NEXT_PUBLIC_API_URL=http://localhost:7836
PORT=3002workslot does not replace your normal env setup.
When you run:
workslot run npm run devthe final environment is assembled in this order:
.env
.env.local
current shell env
generated workslot env
Secrets should stay in .env, .env.local, your shell, or your normal secret manager.
.env.worktree should only contain local ports, local URLs, and other safe per-worktree overrides.
workslot init # create .workslot.json
workslot claim # reserve a slot and write .env.worktree
workslot env # print generated env overlay
workslot run <cmd> [...args] # run a command with env overlay
workslot status # show slots for this project
workslot release # release this worktree slot
workslot doctor # show current slot and port availabilityworkslot stores local state under:
~/.workslot/projects/*.json
The state is local to your machine and keyed by Git project root.
- No app code changes when the app already reads from env.
- No secrets in generated files.
- Stable ports per worktree.
- Explicit config, no framework lock-in.
- Works for Node, Go, Python, Ruby, Rust, Java, Docker, and mixed monorepos.
workslot doctorwith process names for occupied ports.workslot shellto open an interactive shell with the overlay applied.- Docker Compose override generation.
- Homebrew formula and signed GitHub Releases.
- Optional sync to project memory tools for AI coding agents.
MIT