Nodemon vs a Process Manager
Both nodemon and a process manager restart your Node app for you, so it’s easy to assume they’re competitors. They’re not — they’re tools for two different jobs. Confusing them leads to the single most common self-hosting mistake: running nodemon server.js in production.
What nodemon is for
Nodemon watches your source files and restarts the process when you edit code. That’s its whole purpose, and it’s excellent at it:
nodemon --watch src src/server.js Save a file, the server reloads, you refresh the browser. It’s a development-loop tool, in the same category as Vite’s HMR or cargo watch. Its restart trigger is “a file changed” — which is exactly what you want while coding and exactly what you don’t want on a live server.
What a process manager is for
A process manager keeps your app running under real-world conditions: it restarts on crashes, not edits; it survives reboots; it caps memory; it runs health checks; it manages logs; it does zero-downtime reloads. Its restart trigger is “the process died” or “you deployed.”
| nodemon | process manager | |
|---|---|---|
| Restart trigger | File changed | Crash, deploy, health failure |
| Survives reboot | No | Yes |
| Runs in background | No (ties to your terminal) | Yes (daemon) |
| Crash recovery | No | Yes |
| Health checks | No | Yes |
| Log rotation | No | Yes |
| Multiple apps | No | Yes |
| Made for | Development | Production |
Why nodemon in production goes wrong
People reach for nodemon on a server because it “keeps the app up.” It does, until it doesn’t:
- It’s tied to your shell. Close the SSH session and — unless you’ve wrapped it in
nohup/screen/tmux— the app dies with it. Now you’ve bolted a second hack on top. - No reboot survival. The VPS restarts for a kernel update at 4 a.m. and your app doesn’t come back. A process manager registers with systemd and does.
- It watches files you don’t want watched. A log write or an uploaded file in a watched directory can trigger a restart in the middle of serving traffic.
- No crash policy. Nodemon restarts on file changes; it has no concept of max-restart limits, backoff, or health-gated recovery. A crash-looping app just thrashes.
- No logs, no metrics, no reloads. Everything a production app needs operationally, nodemon simply doesn’t do — it was never meant to.
The right split
Use both, each where it belongs:
Development — nodemon (or node --watch, built into modern Node):
node --watch src/server.js Production — a process manager driven by a committed config. With Oxmgr:
[processes.api]
command = "node dist/server.js"
restart_on_exit = true
max_restarts = 10
[processes.api.health_check]
endpoint = "http://localhost:3000/health"
interval_secs = 30 oxmgr start That restarts on crashes, survives reboots, runs a health check, and manages logs — none of which nodemon claims to do.
“But I want auto-reload on deploy”
The legitimate wish behind “nodemon in prod” is usually “restart the app when I ship new code.” That’s a real need — it’s just not nodemon’s file-watch. Two clean ways to do it:
- Deploy-driven restart — your deploy script or git webhook runs
oxmgr reload apiafter pulling, giving you a zero-downtime rollover. - Config-driven watch, deliberately scoped — a process manager’s watch mode restarts on changes to specific build-output paths you name, with debounce and ignore patterns, so a stray log write doesn’t bounce the server.
Both give you “reload on new code” without the footguns of watching your whole source tree on a live box.
Bottom line
Nodemon is a fantastic development tool and a bad production supervisor — not because it’s low quality, but because production reliability was never its job. Keep it in your dev loop. On the server, run a real process manager. If you’re currently nohup nodemon-ing something in production, that’s the first thing to fix.