dev-prism
v0.7.0
Published
Port allocator, env injector, and worktree manager for parallel development sessions
Maintainers
Readme
dev-prism
A port allocator, env injector, and worktree manager for parallel development sessions. Enables multiple Claude Code (or human developer) sessions to work on the same repo simultaneously with complete isolation.
Philosophy
Allocate ports. Inject env. Get out of the way.
dev-prism does three things:
- Allocates unique ports via SQLite (UNIQUE constraints prevent conflicts)
- Injects those ports into any command via
with-env - Optionally manages git worktrees for isolated working directories
Docker is the user's responsibility. dev-prism just hands ports to whatever you run.
Features
- SQLite-backed port allocation with UNIQUE constraints (zero conflicts)
with-envpass-through — injects env vars into any command, no-op outside sessions- Git worktrees for isolated working directories (or in-place mode)
- App-specific env — different env vars for different apps in a monorepo
- Claude Code integration built-in (
dev-prism claude) - Portable: Works with any project, any runtime, any Docker setup
Installation
npm install -g dev-prism
# or
pnpm add -D dev-prismQuick Start
# Create a session (allocates ports + creates worktree)
dev-prism create --branch feature/auth
# Or create in current directory
dev-prism create --in-place
# Start Docker services with allocated ports
dev-prism with-env -- docker compose up -d
# Run app with session env injected
dev-prism with-env my-app -- pnpm dev
# Show allocated ports and env vars
dev-prism info
# Print env vars (for eval or piping)
dev-prism env
# Write .env file for IDE
dev-prism env --write .env
# Destroy session
dev-prism destroyUsage
Create a session
# Create with worktree (generates timestamp-based branch)
dev-prism create
# Custom branch name
dev-prism create --branch feature/my-feature
# In-place mode — use current directory instead of creating worktree
dev-prism create --in-placeInject env and run commands
# Inject session env into any command
dev-prism with-env -- docker compose up -d
dev-prism with-env -- pnpm dev
dev-prism with-env -- cargo run
# Inject app-specific env (merges global + app config)
dev-prism with-env convas-app -- pnpm --filter convas-app dev
dev-prism with-env convas-web -- pnpm --filter convas-web devwith-env is a no-op outside sessions — safe to use unconditionally in scripts and Makefiles.
View env vars
# Print all env vars to stdout
dev-prism env
# Write to file (for IDE/GUI tools)
dev-prism env --write .env
# Include app-specific vars
dev-prism env --app convas-appList sessions
dev-prism listSession info
dev-prism infoCleanup
# Destroy session in current directory
dev-prism destroy
# Destroy all sessions
dev-prism destroy --all
# Remove orphaned sessions from database
dev-prism prune
dev-prism prune -y # Skip confirmationClaude Code integration
dev-prism claude # Install Claude Code skill + CLAUDE.md
dev-prism claude --force # Overwrite existing filesConfiguration
prism.config.mjs
export default {
ports: ['postgres', 'mailpit_http', 'mailpit_smtp', 'app', 'web'],
env: {
POSTGRES_PORT: '${postgres}',
MAILPIT_HTTP_PORT: '${mailpit_http}',
MAILPIT_SMTP_PORT: '${mailpit_smtp}',
DATABASE_URL: 'postgresql://postgres:postgres@localhost:${postgres}/postgres',
},
apps: {
'convas-app': {
PORT: '${app}',
DATABASE_URL: 'postgresql://postgres:postgres@localhost:${postgres}/postgres',
},
'convas-web': { PORT: '${web}' },
},
setup: ['pnpm install'],
};docker-compose.yml (user-managed)
services:
postgres:
image: postgres:16
ports:
- "${POSTGRES_PORT:-5432}:5432"
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
mailpit:
image: axllent/mailpit
ports:
- "${MAILPIT_HTTP_PORT:-8025}:8025"
- "${MAILPIT_SMTP_PORT:-1025}:1025"
volumes:
postgres-data:The :- defaults mean it works without dev-prism too (solo dev, standard ports).
How It Works
dev-prism createallocates ports viaget-port+ SQLite UNIQUE constraintsdev-prism with-env -- <cmd>reads ports from SQLite, renders env templates, injects into command- Docker Compose uses
${VAR:-default}substitution — standard, no dev-prism dependency
Typical workflow
dev-prism create --branch feature/auth
cd ../sessions/feature/auth
dev-prism with-env -- docker compose up -d # infra on allocated ports
dev-prism with-env convas-app -- pnpm dev # app with PORT + DATABASE_URL
# Or in package.json scripts:
# "dev": "dev-prism with-env -- turbo dev"
# "docker:up": "dev-prism with-env -- docker compose up -d"Architecture
SQLite as Source of Truth
Location: <project-root>/.dev-prism/sessions.db
CREATE TABLE sessions (
id TEXT PRIMARY KEY, -- working directory path
branch TEXT,
created_at TEXT NOT NULL
);
CREATE TABLE port_allocations (
session_id TEXT NOT NULL REFERENCES sessions(id) ON DELETE CASCADE,
service TEXT NOT NULL,
port INTEGER NOT NULL UNIQUE, -- prevents cross-session conflicts
PRIMARY KEY (session_id, service)
);Port Allocation Strategy
Two-phase: get-port finds free TCP ports, SQLite UNIQUE prevents cross-session conflicts.
- Query all existing allocated + reserved ports
- Use
get-portto find free ports (excluding existing) - INSERT all in a single transaction
- Retry once on UNIQUE violation (race condition)
with-env Pass-Through
No project root found → exec command as-is
No session in DB → exec command as-is
Session found → render env templates → merge with process.env → execThis makes with-env safe to use unconditionally in scripts, Makefiles, and CI.
Portability
To use in another project:
- Install:
pnpm add -D dev-prism - Create
prism.config.mjswith your ports and env templates - Write your own
docker-compose.ymlusing${VAR:-default}for ports - Run
dev-prism create --in-place
dev-prism doesn't generate any Docker files — you own your Docker setup entirely.
Migration from v0.6.x
v0.7.0 is a breaking change that removes Docker orchestration:
What changed:
- Port allocation: Docker random →
get-port+ SQLite - State storage: Docker labels → SQLite database
- Docker management: Removed (user's responsibility)
- New commands:
with-env,env - Removed commands:
start,stop,stop-all,logs
Migration steps:
- Stop all v0.6 sessions:
dev-prism stop-all(on v0.6.x) - Upgrade:
pnpm add -g [email protected] - Update config to
prism.config.mjswith new format (ports array, env templates) - Write your own
docker-compose.ymlwith${VAR:-default}port substitution - Recreate sessions
License
MIT
