Hot Reload
import { RouteWatcher } from '@routegraph/watcher'
const watcher = new RouteWatcher(graph, { debounceMs: 150 })
watcher.on('reloaded', (diff) => {
console.log(`+${diff.added.length} ~${diff.changed.length} -${diff.removed.length}`)
})
watcher.start()RouteWatcher wraps chokidar. Add, edit, or delete a route file and it
reloads the change directly into the running RouteGraph — no server
restart, no manual graph.load() call.
What triggers a reload
- A route file (
GET.ts,POST.ts, etc.) is added, changed, or removed.
What doesn’t
- Non-route files in a route folder (they were never scanned in the first place).
- Files starting with
_(same reason). - Edits to a shared module a route merely
imports — the watcher tracks route files, not their dependency graph. Changing_shared/db.tswon’t trigger a reload of routes that import it.
WatcherOptions
| Option | Type | Default | Description |
|---|---|---|---|
debounceMs | number | 150 | coalesce rapid saves (editors that write twice) into one reload |
ignored | string | string[] | RegExp | — | extra chokidar ignore patterns |
Events
watcher.on('added', (route) => {})
watcher.on('changed', (route) => {})
watcher.on('removed', (route) => {})
watcher.on('reloaded', (diff) => {}) // fires once per debounced batch
watcher.on('error', (err) => {})Graceful shutdown
process.on('SIGINT', async () => {
await watcher.stop()
process.exit(0)
})
process.on('SIGTERM', async () => {
await watcher.stop()
process.exit(0)
})routegraph dev wires all of this up for you automatically — you only
reach for RouteWatcher directly if you’re building a custom dev server
around @routegraph/core.