Cookbooks and Examples

Ready-to-use configurations for common development scenarios. Copy these commands into Command Book and customize for your projects.

Web Development

Python Web Server

Flask Development Server

flask run --reload --debugger
  • Working directory: Your Flask project root
  • Environment: FLASK_DEBUG=1

Django Development Server

python manage.py runserver 0.0.0.0:8000
  • Working directory: Your Django project root

FastAPI with Uvicorn

uvicorn main:app --reload --host 0.0.0.0 --port 8000

Node.js

Next.js Development

npm run dev

Express Server with Nodemon

npx nodemon server.js

Vite Development Server

npm run dev

Databases

PostgreSQL

Start PostgreSQL (Homebrew)

postgres -D /opt/homebrew/var/postgres

PostgreSQL with Docker

docker run -p 5432:5432 -e POSTGRES_PASSWORD=secret postgres

Valkey (more open Redis fork)

Start Valkey (Homebrew)

valkey-server

Valkey with Docker

docker run -p 6379:6379 valkey/valkey-bundle

MongoDB

MongoDB with Docker

docker run -p 27017:27017 mongo

Docker Compose

Full Stack Setup

docker-compose up

Create multiple commands for different services:

  1. Backend: docker-compose up api
  2. Frontend: docker-compose up web
  3. Database: docker-compose up db

This lets you start/stop services independently. Do not use the -d option as Command Book will think the command has exited when it runs in detatched daemon mode.

Background Workers

Celery Worker

celery -A myapp worker --loglevel=info

Celery Beat (Scheduler)

celery -A myapp beat --loglevel=info

RQ Worker

rq worker --with-scheduler

Log Watching

Tail System Logs

tail -f /var/log/system.log

Watch Docker Logs

docker logs -f container_name

Watch Multiple Files

tail -f *.log

Build Watchers

TypeScript Compiler Watch

tsc --watch

Webpack Watch

webpack --watch

Tailwind CSS Watch

npx tailwindcss -i ./src/input.css -o ./dist/output.css --watch

Testing

Pytest Watch

ptw --runner "pytest --tb=short"

Jest Watch

npm test -- --watch

Tunneling & Networking

ngrok

ngrok http 8000

Local SSL with mkcert

python -m http.server 8000
# In another command:
# mkcert -install && mkcert localhost

Tips for Organizing

Create a typical development setup:

Command Name Command Auto-Restart
API Server flask run Yes
Frontend npm run dev Yes
Database docker-compose up db No
Worker celery worker Yes
Logs tail -f logs/*.log No

Use separators to group:

  • Servers (API, Frontend)
  • Infrastructure (DB, Valkey)
  • Workers (Celery, RQ)
  • Monitoring (Logs, Metrics)

Driving the Stack from a Script

Everything above is a command you save once. The CLI is how you sequence them, which makes these recipes usable from a shell script, a Makefile, a CI job, or an AI coding agent.

Bring up a stack, use it, tear it down:

#!/usr/bin/env bash
set -euo pipefail

# Register the cleanup first, so it still runs if a start or a test fails.
trap 'commandbook stop --all' EXIT

# Start the pieces in dependency order. `start` returns as soon as each is up,
# and fails loudly (with the tail of its output) if one dies on the way up.
commandbook start postgres
commandbook wait  postgres --port 5432

commandbook start api-server
commandbook wait  api-server --http http://127.0.0.1:5000

commandbook start celery-worker

# The stack is up and actually answering. Do the real work.
pytest tests/integration

wait --port/--http is the piece that replaces sleep 5 && hope: it returns the instant the endpoint answers, and fails fast (exit 205) if the process dies during boot rather than burning the timeout.

Find out why one of them fell over:

commandbook logs api-server --grep "Traceback|ERROR" --since 10m
commandbook logs api-server --runs          # what runs are still retained?
commandbook logs api-server --run 2         # read the run before the restart

Provision the commands themselves, so a fresh clone gets a working command book:

commandbook new --name "API Server" --command "flask run" --dir . \
                --auto-restart --if-not-exists
commandbook new --name "Frontend" --command "npm run dev" --dir ./web \
                --if-not-exists

--if-not-exists makes that safe to re-run: an existing slug is a no-op instead of an error, so the script is idempotent.

See the CLI documentation for every flag, and the AI Agents guide for wiring this loop into Claude Code, Codex, or Cursor.