Skip to content
Projects

jdx/pitchfork has 716 GitHub stars and 51 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-15 18:45 UTC. Last push 2026-11-14.

How these counts are measured

Measured star growth

in 24h
0
in 7 days
Collecting history
in 15 days
Collecting history
in 1 month
Collecting history

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

About

Daemons with DX

Developer Tools

README.md

Original
pitchfork

pitchfork

Your project's background services, under control.

Start once. Wait for readiness. Get back to work.

Crates.io version CI status MIT license

Quickstart · Guides · CLI reference

Pitchfork manages the long-running commands your project needs: an API, a database, a frontend server, or a background worker. Define them in pitchfork.toml, then start, inspect, and stop them from any terminal. A background supervisor keeps track of the processes and their logs after the CLI exits.

Get started

Install with mise:

mise use -g pitchfork

You can also use cargo install pitchfork-cli --locked or download a binary from GitHub releases. See installation for platform details and shell completion.

Try a daemon without a config file (requires Python 3):

pitchfork run demo --port 8000 -- \
  python3 -u -m http.server 8000 --bind 127.0.0.1
pitchfork status demo
pitchfork logs demo --tail
# Ctrl+C leaves the daemon running. Stop it when you're done:
pitchfork stop demo

Open localhost:8000 while the daemon is running.

Put your services in version control

Create pitchfork.toml in your project. This example assumes Redis is installed and your project has a server.js that reads PORT and REDIS_URL:

#:schema https://pitchfork.jdx.dev/schema.json

[daemons.redis]
run = "redis-server --port $PORT"
port = 6379
ready_cmd = "redis-cli -p $PORT ping"

[daemons.api]
run = "node server.js"
port = 3000
depends = ["redis"]
env = { REDIS_URL = "redis://127.0.0.1:{{ daemons.redis.port }}" }
ready_http = { url = "http://127.0.0.1:3000/health", timeout = "30s" }
retry = 3
pitchfork start api       # Starts Redis first, then waits for the API's health check
pitchfork start --local   # Starts all daemons in the project's merged local config
pitchfork list --project  # Shows this project's daemons
pitchfork restart api     # Applies config changes and restarts the API
pitchfork stop --local    # Stops local services in reverse dependency order

Starting an already running daemon leaves it running. Independent dependencies start in parallel. --all includes global daemons as well as local ones.

Make it fit your workflow

When you need to… Use…
Start services when you enter a project Shell hooks with auto = ["start", "stop"]
Wait for a service to accept requests Ready checks using output, HTTP, TCP, or a command
Recover from a crash or failed health probe Retries and health checks
Restart after a source edit File watching with glob patterns
Keep a stable URL across port changes Port assignment and reverse proxy
Inspect services and their output pitchfork tui, the web UI, and structured logs
Run tasks on a schedule Cron scheduling
Connect an AI assistant The built-in MCP server

The docs also cover namespaces and worktrees, mise integration, lifecycle hooks, and resource limits.

Contribute

See CONTRIBUTING.md for setup, checks, and documentation development. Found a problem? Include your version, config, and relevant logs in a GitHub issue.

Sponsors

Sponsored by

Entire     Omacom Foundation

View all sponsors

Contributors