Skip to content

moinsen-dev/devhub

Repository files navigation

DevHub

Multi-project development environment manager - Start, stop, and monitor all your local development services from one place.

License: MIT Rust Release Docs

The Problem

Working on multiple projects means juggling multiple terminals:

# Project A
cd ~/work/project-a && npm run dev        # Terminal 1
cd ~/work/project-a && cargo run          # Terminal 2

# Project B
cd ~/work/project-b && docker compose up  # Terminal 3
cd ~/work/project-b && npm start          # Terminal 4

# Which ports? Which commands? Where's that README again?

The Solution

devhub start project-a    # Starts all services
devhub start project-b    # Starts all services
devhub status             # See everything at a glance

# Or open http://devhub.localhost for the dashboard

Features

  • One command to rule them all - devhub start launches your entire stack
  • Bulk discovery - Scan directories and register 100+ projects at once
  • Monorepo support - Auto-detects multi-service projects (frontend + backend + packages)
  • Environment file loading - Automatic .env and .env.local support with variable interpolation
  • Web dashboard - Visual status, start/stop buttons, log viewer, real-time updates
  • Fuzzy search - Find projects fast with devhub search
  • Favorites & Recent - Star projects, track recently used
  • Batch operations - devhub start --all or --favorites
  • Auto-discovery - Detects Rust, Node, Python, Go, Docker, Flutter projects
  • Port conflict detection - Know before you crash with devhub ports --resolve
  • PM2 integration - Node.js services managed properly
  • Docker Compose support - First-class container orchestration
  • Health checks - Wait for services to be truly ready
  • Reverse proxy integration - Pretty URLs like http://myproject.localhost
  • Shell completions - Tab completion for bash, zsh, and fish
  • Developer shortcuts - devhub code, devhub open, devhub path
  • Zero lock-in - Simple TOML config, works with any stack

Quick Start

1. Install DevHub

# Homebrew (macOS)
brew tap moinsen-dev/tap
brew install devhub

# Or download pre-built binary
curl -sL https://github.com/moinsen-dev/devhub/releases/latest/download/devhub-aarch64-apple-darwin.tar.gz | tar xz
sudo mv devhub /usr/local/bin/

# Or from source
git clone https://github.com/moinsen-dev/devhub.git && cd devhub
cargo build --release && cp target/release/devhub ~/.local/bin/

2. Discover Your Projects

# Scan your project directories
devhub scan --dry-run ~/work

# Found 50 projects? Register them all!
devhub scan --auto-register ~/work

3. Install Shell Completions

# Zsh (most common on macOS)
devhub completions zsh > ~/.zfunc/_devhub

# Bash
devhub completions bash > ~/.local/share/bash-completion/completions/devhub

# Fish
devhub completions fish > ~/.config/fish/completions/devhub.fish

4. Start Working

# Start a project
devhub start my-project

# Check status
devhub status

# Quick navigation
cd $(devhub path my-project)  # Jump to project directory
devhub code my-project        # Open in VS Code
devhub open my-project        # Open in browser

# Check for port conflicts
devhub ports --check

5. Launch the Dashboard (Optional)

# Start the daemon as a background service
devhub daemon start

# Or if installed via Homebrew
brew services start devhub

# Start the UI
cd devhub-ui && npm install && npm run dev

# Open http://localhost:5173

CLI Reference

Project Management

devhub init                    # Create devhub.toml in current directory
devhub discover                # Auto-detect and generate devhub.toml
devhub discover --dry-run      # Preview discovery without writing files
devhub register [path]         # Register project with DevHub
devhub unregister <name>       # Remove project from registry
devhub list                    # List all registered projects

Bulk Operations

devhub scan [paths...]         # Scan directories for projects
devhub scan --dry-run          # Preview what would be discovered
devhub scan --auto-register    # Discover and register in one step
devhub scan --depth 3          # Scan deeper into subdirectories

Service Control

devhub start [project]         # Start project services
devhub start --all             # Start ALL registered projects
devhub start --favorites       # Start all favorite projects
devhub stop [project]          # Stop project services
devhub restart [project]       # Restart project services
devhub status                  # Show status of all projects
devhub logs <project> [-f]     # Stream logs (with follow mode)

Discovery & Search

devhub search <query>          # Fuzzy search for projects
devhub recent                  # Show recently used projects
devhub fav add <project>       # Add to favorites
devhub fav list                # List favorites
devhub fav toggle <project>    # Toggle favorite status

Port Management

devhub ports                   # Show all port allocations
devhub ports --check           # Detect port conflicts
devhub ports --resolve         # Suggest fixes for conflicts

Developer Shortcuts

devhub open <project>          # Open project in browser
devhub open <project> -s api   # Open specific service
devhub code <project>          # Open project in VS Code
devhub path <project>          # Print project path (for cd integration)

Environment & Utilities

devhub env <project>           # Show resolved environment variables
devhub env <project> -s api    # Show env for specific service
devhub env <project> -f export # Output in shell export format
devhub completions <shell>     # Generate shell completions (bash/zsh/fish)

Daemon Management

devhub daemon                  # Run daemon in foreground (default)
devhub daemon start            # Start daemon as background service
devhub daemon stop             # Stop running daemon
devhub daemon restart          # Restart daemon
devhub daemon status           # Show daemon status and version
devhub daemon --port 9876      # Run on custom port

Configuration

Each project gets a devhub.toml file:

[project]
name = "my-app"
description = "My awesome application"
tags = ["rust", "web"]
env_files = [".env", ".env.local"]  # Environment files to load

[[services]]
name = "api"
type = "rust-binary"
command = "cargo run --release"
port = 8080
health_check = "/health"
subdomain = "api"           # http://api.my-app.localhost
env_file = "api/.env"       # Service-specific env file

[[services]]
name = "frontend"
type = "node"
command = "npm run dev"
cwd = "frontend"            # Relative working directory
port = 3000
main = true                 # http://my-app.localhost (no subdomain)
depends_on = ["api"]        # Start order

[environment]
RUST_LOG = "info"
DATABASE_URL = "postgres://localhost/myapp"

Environment Loading Priority

Environment variables are loaded in this order (later sources override earlier):

  1. System environment variables
  2. Project root .env file
  3. Project root .env.local file
  4. Files listed in env_files
  5. [environment] section in manifest
  6. Service-specific env_file
  7. Service cwd/.env file
  8. Service cwd/.env.local file
  9. Service env = {} section
  10. DevHub service URL injection (see below)

Variable interpolation is supported: DATABASE_URL=$DB_HOST:$DB_PORT/mydb

Service URL Environment Variables

DevHub automatically injects environment variables for service-to-service communication. This solves the common problem of hardcoding localhost:PORT in your .env files.

Auto-Injected Variables

For every service in your project, DevHub injects:

Variable Example Description
DEVHUB_<SERVICE>_URL http://api.myapp.localhost External URL via Caddy reverse proxy
DEVHUB_<SERVICE>_INTERNAL_URL http://myapp-api:8080 Internal URL for container-to-container
DEVHUB_<SERVICE>_PORT 8080 Service port

Example for a project with api and frontend services:

DEVHUB_API_URL=http://api.myapp.localhost
DEVHUB_API_INTERNAL_URL=http://myapp-api:8080
DEVHUB_API_PORT=8080
DEVHUB_FRONTEND_URL=http://myapp.localhost
DEVHUB_FRONTEND_INTERNAL_URL=http://myapp-frontend:3000
DEVHUB_FRONTEND_PORT=3000

Service Reference Syntax

You can reference other services in your devhub.toml using the ${service.property} syntax:

[[services]]
name = "frontend"
type = "node"
command = "npm run dev"
port = 3000
main = true

[services.env]
# These get auto-expanded by DevHub:
NEXT_PUBLIC_API_URL = "${api.url}"           # → http://api.myapp.localhost
INTERNAL_API_URL = "${api.internal}"         # → http://myapp-api:8080
API_PORT = "${api.port}"                     # → 8080

Available properties:

  • ${service.url} - External URL (via Caddy, for browser/client-side)
  • ${service.internal} - Internal URL (for container-to-container communication)
  • ${service.port} - Service port number

Use Case: Next.js + Python Backend

[project]
name = "demo-app"
mode = "container"

[[services]]
name = "backend"
type = "python"
command = "uvicorn main:app --host 0.0.0.0 --port 8081"
port = 8081
subdomain = "api"

[[services]]
name = "frontend"
type = "node"
command = "npm run dev"
port = 3000
main = true

[services.env]
# Client-side API calls go through Caddy
NEXT_PUBLIC_API_URL = "${backend.url}"

Your frontend automatically gets NEXT_PUBLIC_API_URL=http://api.demo-app.localhost - no more hardcoded localhost:8081!

Service Types

Type Detection Default Command
rust-binary Cargo.toml with [[bin]] cargo run
node package.json npm run dev (uses PM2 if available)
python pyproject.toml uvicorn or python -m
go go.mod go run .
docker-compose docker-compose.yml docker compose up -d
shell Any Custom command

Dashboard

The web dashboard provides:

  • Project cards with running status indicators
  • One-click start/stop/restart buttons
  • Log viewer with auto-refresh and syntax highlighting
  • Service-level controls (start/stop individual services on hover)
  • Real-time auto-refresh (5-second polling)
  • Search and filter by name or status
  • Service metrics (X/Y services running)
  • Open in Terminal / VS Code buttons

Access:

  • http://devhub.localhost (with Caddy proxy)
  • http://localhost:5173 (development mode)

Reverse Proxy Setup

DevHub auto-generates Caddy configurations for pretty .localhost URLs.

Quick Setup

cd proxy
docker compose up -d

This gives you:

  • http://projectname.localhost - Your main service
  • http://api.projectname.localhost - API services
  • http://devhub.localhost - Dashboard

Custom Proxy Location

mkdir -p ~/.devhub
cat > ~/.devhub/config.toml << EOF
caddy_sites_dir = "/path/to/your/proxy/sites.d"
caddy_reload_command = "docker exec caddy-proxy caddy reload --config /etc/caddy/Caddyfile"
EOF

Project Structure

devhub/
├── src/                  # Rust CLI + daemon
│   ├── main.rs           # CLI entry (clap)
│   ├── api.rs            # REST API (axum)
│   ├── process.rs        # Service management (PM2, Docker, native)
│   ├── discovery.rs      # Auto-detection (6 project types)
│   ├── manifest.rs       # TOML parsing
│   ├── registry.rs       # Project registry (+ favorites, recent)
│   ├── ports.rs          # Port allocation & conflict detection
│   ├── caddy.rs          # Proxy config generation
│   └── config.rs         # Global settings
├── devhub-ui/            # SvelteKit dashboard (Svelte 5)
├── proxy/                # Caddy reverse proxy setup
└── Cargo.toml            # Rust dependencies

Troubleshooting

Port shows as "not running" but service is up

DevHub checks both IPv4 and IPv6. If issues persist:

lsof -i :3000

PM2 not being used

PM2 must be installed globally:

npm install -g pm2

Service won't start

# Check logs
devhub logs my-project my-service

# Or directly
cat ~/Library/Application\ Support/com.moinsen.devhub/logs/my-project/my-service.err.log

Caddy not reloading

docker exec caddy-proxy caddy reload --config /etc/caddy/Caddyfile
docker logs caddy-proxy

Installation

Homebrew (macOS)

brew tap moinsen-dev/tap
brew install devhub

# Start as background service (optional)
brew services start devhub

Pre-built Binaries

Download from GitHub Releases:

# macOS Apple Silicon
curl -sL https://github.com/moinsen-dev/devhub/releases/latest/download/devhub-aarch64-apple-darwin.tar.gz | tar xz
sudo mv devhub /usr/local/bin/

# macOS Intel
curl -sL https://github.com/moinsen-dev/devhub/releases/latest/download/devhub-x86_64-apple-darwin.tar.gz | tar xz
sudo mv devhub /usr/local/bin/

# Linux x64
curl -sL https://github.com/moinsen-dev/devhub/releases/latest/download/devhub-x86_64-unknown-linux-gnu.tar.gz | tar xz
sudo mv devhub /usr/local/bin/

# Linux ARM64
curl -sL https://github.com/moinsen-dev/devhub/releases/latest/download/devhub-aarch64-unknown-linux-gnu.tar.gz | tar xz
sudo mv devhub /usr/local/bin/

From Source

git clone https://github.com/moinsen-dev/devhub.git
cd devhub
cargo build --release
cp target/release/devhub ~/.local/bin/

Cargo (crates.io) - Coming Soon

cargo install devhub

Contributing

Contributions welcome! See CONTRIBUTING.md for guidelines.

License

MIT License - see LICENSE for details.


Acknowledgments

  • Caddy - The reverse proxy that makes this possible
  • axum - Excellent Rust web framework
  • clap - CLI argument parsing with completions
  • PM2 - Node.js process management
  • SvelteKit - Clean, fast UI framework

"Stop remembering. Start building."

About

Start, stop, and monitor all your local development services from one place.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •