Skip to content

chamitachama/wtree

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

92 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

wtree

npm version npm downloads license

Run multiple git worktrees in parallel, each with its own full-stack environment on isolated ports.

Install

npm install -g @chamitachama/wtree

Or with aliases for convenience:

npm install -g @chamitachama/wtree
alias wtree='npx @chamitachama/wtree'

Quick Start

wtree init                    # detect services + write .wtree.json
wtree open feature/my-branch  # start workspace with isolated ports
wtree list                    # see all workspaces
wtree stop my-branch          # stop processes, keep worktree
wtree destroy my-branch       # stop + delete worktree

Setup

In your project root:

wtree init

Auto-detects services from docker-compose.yml, Procfile, or package.json and writes .wtree.json.

What gets detected

  • App services β€” ports, names, base commands
  • Infrastructure β€” MongoDB, Redis, Postgres with host-mapped ports
  • Connection strings β€” auto-generated for detected infra

Configuration

Full example

{
  "defaultBranch": "main",
  "workspacesDir": ".worktrees",
  "portStep": 100,

  // Copy .env files from main repo into each new worktree
  "envFiles": [
    { "path": "./backend/.env", "required": ["DATABASE_URL"] },
    "./frontend/.env"
  ],

  // Auto-detected from docker-compose (or configure manually)
  "infrastructure": {
    "mongodb": "mongodb://localhost:27018",
    "redis": "redis://localhost:6380"
  },

  // Run once when worktree is first created
  "setup": [
    { "command": "pnpm install --frozen-lockfile", "cwd": "." },
    { "command": "poetry install", "cwd": "./backend" }
  ],

  "services": [
    {
      "name": "backend",
      "command": "uvicorn src.main:app --reload",
      "cwd": "./backend",
      "basePort": 8000,
      "portEnvVar": "PORT",
      "shared": true,
      "healthCheck": {
        "url": "http://localhost:{port}/health",
        "timeout": 30000
      },
      "env": {
        "DATABASE_URL": "{infrastructure.mongodb}",
        "REDIS_URL": "{infrastructure.redis}"
      }
    },
    {
      "name": "frontend",
      "command": "pnpm dev",
      "cwd": "./frontend",
      "basePort": 3000,
      "portEnvVar": "PORT",
      "dependsOn": ["backend"],
      "env": {
        "NEXT_PUBLIC_API_URL": "http://localhost:{backend.port}"
      }
    }
  ]
}

Template variables

Variable Description Example
{service.port} Another service's assigned port http://localhost:{backend.port}
{infrastructure.<type>} Infrastructure connection string {infrastructure.mongodb}

Port allocation

Each workspace gets a slot (1, 2, 3...). Actual port = basePort + (slot Γ— portStep).

Workspace Slot frontend backend
feature-a 1 3100 8100
feature-b 2 3200 8200

PR integration

Open a GitHub PR directly by number:

wtree open pr/123    # or pr#123
# πŸ” Fetching PR #123 info...
# βœ“ PR #123 β†’ feat/my-feature-branch
# Opening workspace: feat/my-feature-branch

Requires gh CLI to be installed and authenticated.

Health checks & dependencies

Define health checks and service dependencies to ensure proper startup order:

"services": [
  {
    "name": "backend",
    "command": "uvicorn main:app",
    "basePort": 8000,
    "healthCheck": {
      "url": "http://localhost:{port}/health",
      "timeout": 30000
    }
  },
  {
    "name": "frontend",
    "command": "pnpm dev",
    "basePort": 3000,
    "dependsOn": ["backend"]  // Waits for backend health check
  }
]

Output:

βœ“ backend β†’ http://localhost:8100
  ⏳ Waiting for backend... ready
βœ“ frontend β†’ http://localhost:3100

Shared services

Mark a service as shared: true to run a single global instance instead of one per worktree:

"services": [
  { "name": "backend", "shared": true, "basePort": 8000, ... },  // one instance
  { "name": "frontend", "basePort": 3000, ... }  // per worktree
]
  • Shared services run from the main repo root (not the worktree)
  • Use fixed basePort (no slot offset)
  • Start once, reused across all worktrees
  • Not stopped when individual worktrees stop
  • wtree init asks interactively which services to share

Commands

Workspace management

wtree init                         # Detect services, write .wtree.json
wtree open <branch>                # Open existing branch as workspace
wtree open <branch> --skip-setup   # Skip setup commands (deps already installed)
wtree create <name>                # Create new branch + workspace
wtree create <name> --from <base>  # Branch off a specific base
wtree create <name> --skip-setup   # Skip setup commands
wtree list                         # Show all workspaces + ports
wtree stop <name>                  # Stop processes, keep worktree
wtree destroy <name>               # Stop + delete (requires typing DELETE)

Utilities

wtree browser <name>    # Open workspace frontend in browser
wtree logs <name>       # Tail logs for a workspace
wtree claude <name>     # Launch Claude Code in workspace context
wtree sync-env <name>          # Sync env vars from base to worktree
wtree sync-env <name> --force  # Also overwrite differing values

Features

πŸ” Environment files

Copy .env files from your main repo into each worktree automatically:

// Simple format
"envFiles": ["./backend/.env", "./frontend/.env"]

// With required vars verification
"envFiles": [
  { "path": "./backend/.env", "required": ["DATABASE_URL", "REDIS_URL"] },
  { "path": "./frontend/.env", "required": ["NEXT_PUBLIC_API_URL"] }
]
  • Copies on first open or create
  • Syncs new vars on subsequent opens (appends missing vars without overwriting)
  • Warns when values differ between base and worktree
  • Skips if file doesn't exist in main repo (warning)
  • Warns if required vars are missing
# Sync on demand
wtree sync-env my-workspace

# Force overwrite differing values
wtree sync-env my-workspace --force

πŸ“¦ Setup commands

Run install/build commands when a worktree is first created:

"setup": [
  { "command": "pnpm install", "cwd": "." },
  { "command": "poetry install", "cwd": "./backend" }
]
  • Runs sequentially (order matters)
  • Creates .wtree-setup-done marker to avoid re-running
  • Use --skip-setup to bypass

🐳 Infrastructure detection

wtree init parses docker-compose.yml to find infrastructure services:

πŸ“¦ Detected infrastructure services:
  β€’ mongodb (mongodb) β†’ localhost:27018
  β€’ redis (redis) β†’ localhost:6380

πŸ’‘ Tip: Use {infrastructure.<type>} in service env vars

Supported: MongoDB, Redis, PostgreSQL, MySQL, RabbitMQ

♻️ Workspace reuse

When you stop a workspace and later open it again, wtree reuses the same slot and ports instead of creating duplicates.

Example workflow

# Setup (once)
wtree init
# πŸ“‹ Detected services:
#   β€’ backend (port 8000)
#   β€’ frontend (port 3000)
# 
# Share backend across all worktrees? (y/N) y
# Share frontend across all worktrees? (y/N) n
#
# βœ“ backend β†’ port 8000 [shared]
# βœ“ frontend β†’ port 3000
# βœ“ Wrote .wtree.json

# Daily workflow
wtree open feat/LON-123-new-feature
# πŸ” Copying .env files...
#   βœ“ ./backend/.env
#     βœ“ All required vars present (1)
# πŸ“¦ Running setup commands...
#   β†’ pnpm install (in .)
# βœ“ backend β†’ http://localhost:8000 (shared)
# βœ“ frontend β†’ http://localhost:3100

# Work on another feature in parallel
wtree open feat/LON-456-hotfix
# ↳ backend β†’ http://localhost:8000 (shared, already running)
# βœ“ frontend β†’ http://localhost:3200

# Check status
wtree list
# ● feat-LON-123-new-feature  frontend:3100
# ● feat-LON-456-hotfix       frontend:3200
# β—† backend (shared)          :8000

# Done with a feature
wtree destroy feat-LON-123-new-feature
# ⚠️  Type DELETE to confirm: DELETE
# Destroyed workspace (shared services kept running)

Files

Path Description
.wtree.json Configuration file
.wtree/state.json Active workspaces state
.wtree/logs/ Service log files
.wtree/STATUS.md Human-readable status doc
.worktrees/ Git worktree directories

Add to .gitignore:

.worktrees/
.wtree/state.json

License

MIT

About

Run multiple git worktrees in parallel, each with its own full-stack environment on isolated ports

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors