Feature worktrees & isolated environments
Develop each feature in its own git worktree with a fully isolated runtime — its
own postgres database, its own ports, its own .env — all derived from the
branch name. One shared platform-db container hosts one database per branch;
pg-boss creates its pgboss schema inside that database, so queue isolation
comes for free.
Two reusable scripts cover the whole lifecycle:
| Command | What it does |
|---|---|
bun run worktree create | Create the worktree (branch + port offset + bun install) |
bun run env:feature | Provision the isolated env (branch DB + .env files + migrate) |
bun run worktree list | List all worktrees |
bun run env:feature:down | Drop the branch database |
bun run worktree remove | Remove the worktree |
1. Create the worktree
Section titled “1. Create the worktree”bun run worktree create feat/my-feature # auto-assigns next free port offsetbun run worktree create feat/my-feature 100 # pin a port offsetCreates ../platform-worktrees/feat/my-feature, assigns the next free port
offset, runs bun install, and opens Warp tabs. Flags: --no-open,
--no-install.
2. Provision the isolated environment
Section titled “2. Provision the isolated environment”Run this inside the new worktree:
cd ../platform-worktrees/feat/my-featurebun run env:featureThis derives a slug + port offset from the branch name, seeds .env,
apps/api/.env, apps/dashboard/.env, and apps/developer-website/.env from
the main worktree, rewrites them to point at an isolated postgres database
(platform_<slug>) and offset ports (API 3000+offset, Dashboard
5000+offset, Dev website 5003+offset), then runs migrations. It is
idempotent — re-running reuses the existing offset/DB and only fills gaps.
Then develop as usual:
bun run dev # API + dashboardbun run developer-website # docs/marketing site (developer.viite.ai), offset port3. Tear down when the feature merges
Section titled “3. Tear down when the feature merges”bun run env:feature:down # drop the branch databasebun run env:feature:down --purge # ...and remove the worktree .env filesbun run worktree remove feat/my-feature # remove the worktreebun run worktree remove feat/my-feature --delete-branch --forceGotchas
Section titled “Gotchas”- Dual-React invalid-hook error. If the dashboard fails in a worktree
(tailwind-resolve, then
useMemo of null/ “invalid hook call”), remove the symlinkedapps/dashboard/node_modulesand runbun installat the worktree root. Vite aliasesplatform-uito source, so any split React copy breaks hooks. - Vite doesn’t see
.env. Bun doesn’t inject.envinto a spawned Vite, so always useenv:feature(which handles theloadEnvwiring) rather than hand-rolling.envfiles. The same applies to the Astro dev server (apps/developer-website): itsastro.config.mjsreadsDEVELOPER_WEBSITE_PORTvialoadEnvfrom its own dir, so the port offset only binds when theapps/developer-website/.envwritten byenv:featureis present.
