Nodemon Configuration: Reproducible Restarts with nodemon.json
Move nodemon's watch, ignore, exec, and delay settings into a committed nodemon.json so every teammate gets identical restart behavior — and learn why ignoring output directories prevents restart loops.
23 Mar 2026, 21:39 UTC

The problem: restart behavior that lives in one developer's shell history
Nodemon works fine out of the box, but the moment a project needs anything beyond the defaults — watching only src/, skipping test files, debouncing a formatter's burst of saves — the settings end up as a long CLI invocation in one person's terminal alias. The next teammate gets different restart behavior, or none. The fix is to move that configuration into a committed nodemon.json file so everyone on the team gets identical behavior from npm run dev.
The useful takeaway: nodemon's entire watch/ignore/exec/delay surface can be declared in one JSON file, CLI flags still override it when needed, and npx nodemon --dump shows you the exact computed configuration so nothing is guesswork.
How nodemon actually restarts your app
Nodemon is a file watcher wrapped around a child process. It watches a set of paths, and when a matching file changes it kills the child process and spawns a fresh one. Two consequences follow from that mechanism:
- There is no hot-swapping. Every restart is a brand-new process, so all in-memory state — caches, connections, in-flight requests — is lost. Design dev-time code around fast startup, not state preservation.
- Your app runs as a child. Signals like SIGINT and SIGTERM are forwarded by nodemon, so graceful-shutdown handlers in your app still work, but environment and signal behavior differ subtly from running
nodedirectly.
A worked nodemon.json
Place this in the project root (or point at it with --config):
{
"watch": ["src"],
"ext": "js,json",
"ignore": ["src/**/*.test.js", "logs/**", "uploads/**"],
"delay": "500",
"exec": "node server.js",
"execMap": {
"js": "node --inspect"
}
}What each piece does:
watchrestricts monitoring tosrc/instead of the whole project tree.extlimits which file extensions trigger restarts.ignoreexcludes test files and — critically — directories your app writes to, likelogs/anduploads/.delayis a debounce in milliseconds: a formatter rewriting five files in one save burst produces one restart 500 ms after the last change, not five restarts.execis the command to run;execMapmaps extensions to interpreters, which is how a team can standardize the--inspectdebug flag without touching package scripts.
Wire it into package.json once:
"scripts": {
"dev": "nodemon"
}Run it with npm run dev from the project root. No special permissions are needed beyond a normal dev install (npm install --save-dev nodemon). Any CLI flag you add — say, nodemon --delay 1000 — overrides the file for that invocation only.
Verify the config was picked up
Run this in the project root:
npx nodemon --dumpThis prints the computed effective configuration. Check that your watch, ignore, ext, and exec values appear as expected. Then do a functional check: edit a file in src/ and confirm exactly one restart occurs after the delay; create a file under logs/ and confirm no restart fires; type rs and press Enter to confirm a manual restart still works (useful when a change to an ignored file should trigger one).
Limits and common mistakes
- Restart loops from self-written files. If your app writes logs, uploads, or build output into a watched directory, each restart triggers a change that triggers another restart. Always ignore output directories — this is the most common nodemon failure mode.
- Watching too broadly. The default watches the working directory. On large projects that means scanning
node_modules-adjacent churn; restrictingwatchto source folders cuts CPU usage noticeably. - Using nodemon in production. Nodemon is a development dependency. It is not a process supervisor — it won't handle crashes the way systemd, PM2, or a container restart policy will, and it adds a watcher you don't need in production.
- Assuming defaults across versions. Default watched extensions and the legacy polling mode have changed across major versions. Check the installed version's docs or
--dumpoutput rather than assuming behavior from an old tutorial.
Nodemon can also restart non-Node programs — "exec": "python app.py" with "ext": "py" turns it into a generic watch-and-respawn tool — but the same dev-only caveat applies.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.