File Watching
Automatically restart daemons when source files change. This is useful for development workflows where you want hot-reloading behavior.
Basic Configuration
Add the watch field to your daemon configuration with glob patterns:
[daemons.api]
run = "npm run dev"
watch = ["src/**/*.ts", "package.json"]When any .ts file in src/ or package.json changes, the daemon will automatically restart.
How It Works
- On supervisor start: Pitchfork scans all daemons for
watchpatterns - Directory watching: Patterns are expanded and their parent directories are watched recursively
- File change detection: The
notifycrate detects file changes with debouncing (1 second) - Pattern matching: Changed files are matched against glob patterns
- Auto-restart: Running daemons with matching patterns are automatically restarted
TIP
Only running daemons are restarted. If a daemon is stopped, file changes won't start it.
Glob Pattern Syntax
Patterns use standard glob syntax:
| Pattern | Matches |
|---|---|
*.js | All .js files in the daemon's directory |
src/**/*.ts | All .ts files in src/ and subdirectories |
package.json | Specific file |
lib/**/*.py | All .py files in lib/ and subdirectories |
config/*.toml | All .toml files in config/ directory |
Patterns are resolved relative to the pitchfork.toml file that defines the daemon.
Examples
Node.js Development Server
[daemons.api]
run = "npm run dev"
watch = ["src/**/*.ts", "src/**/*.tsx", "package.json", "tsconfig.json"]
ready_http = "http://localhost:3000/health"Python Flask App
[daemons.flask]
run = "flask run --reload"
watch = ["app/**/*.py", "templates/**/*.html", "requirements.txt"]
ready_port = 5000Go Service
[daemons.server]
run = "go run ./cmd/server"
watch = ["**/*.go", "go.mod", "go.sum"]
ready_port = 8080Multi-Service Setup
[daemons.postgres]
run = "postgres -D /var/lib/pgsql/data"
ready_port = 5432
# No watch - database doesn't need hot reload
[daemons.api]
run = "npm run dev"
depends = ["postgres"]
watch = ["src/**/*.ts", "package.json"]
ready_http = "http://localhost:3000/health"
[daemons.worker]
run = "npm run worker"
depends = ["postgres"]
watch = ["src/worker/**/*.ts", "package.json"]Combining with Other Features
With Ready Checks
File watching works well with ready checks to ensure the daemon is fully restarted:
[daemons.api]
run = "npm run dev"
watch = ["src/**/*.ts"]
ready_http = "http://localhost:3000/health" # Wait for health endpointWith Auto Start/Stop
Combine with shell hook for full development workflow automation:
[daemons.api]
run = "npm run dev"
watch = ["src/**/*.ts"]
auto = ["start", "stop"] # Auto-start when entering directoryWith Retry
If your daemon might fail during restart, add retry:
[daemons.api]
run = "npm run dev"
watch = ["src/**/*.ts"]
retry = 3 # Retry up to 3 times if restart failsPerformance Considerations
- Debouncing: Changes are debounced for 1 second to avoid rapid restarts during batch saves
- Directory watching: Only unique parent directories are watched, not individual files
- Recursive watching: Subdirectories are watched automatically for
**patterns - Running daemons only: Stopped daemons ignore file changes
Troubleshooting
Files not triggering restart
- Check the pattern matches your files (patterns are case-sensitive)
- Ensure the daemon is running (
pitchfork list) - Check supervisor logs for watch registration messages
Too many restarts
- Add more specific patterns to avoid matching build artifacts
- Exclude directories like
node_modules,target,.git:tomlwatch = ["src/**/*.ts"] # Only watch src/, not node_modules
Restart delay
File changes are debounced for 1 second. If you're making rapid edits, only the final state triggers a restart.
