Every time you save a file while developing your Express server, you have to stop the running process and restart it manually before your changes take effect. After the third or fourth time in a row this becomes painful and breaks your development flow. nodemon solves this completely โ it watches your project files for changes and automatically restarts the Node.js process the moment you save. In this lesson you will install and configure nodemon, create a nodemon.json configuration tailored for MERN development, and end the manual restart cycle for good.
What nodemon Does
| Without nodemon | With nodemon |
|---|---|
| Save a file | Save a file |
| Ctrl+C to stop the server | nodemon detects the change automatically |
| Press Up arrow, Enter to restart | nodemon restarts the server automatically |
| Wait for server to start | Server is ready in under a second |
| Switch back to browser/Postman to test | Switch back to browser/Postman to test |
devDependencies and the production "start" script uses plain node index.js while the "dev" script uses nodemon index.js.--ext flag or the ext field in nodemon.json to also watch .json files (useful if you have config files or seed data), .env files, and even .html files for email templates. Watching .env files is especially useful since environment variable changes require a server restart to take effect.delay option in nodemon.json to add a short debounce delay between a file change and the restart.Installation and Basic Usage
# Install as a dev dependency (you should have done this in Chapter 2)
cd server
npm install -D nodemon
# Run directly (without package.json script)
npx nodemon index.js
# Run via npm script (recommended โ add to package.json first)
npm run dev
// server/package.json
{
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js"
},
"devDependencies": {
"nodemon": "^3.0.3"
}
}
nodemon.json โ Configuration File
// server/nodemon.json โ place in the server directory root
{
"watch": ["src", "index.js", ".env"],
"ext": "js,json,env",
"ignore": ["node_modules", "src/logs/*", "*.test.js", "*.spec.js"],
"delay": 500,
"env": {
"NODE_ENV": "development"
},
"exec": "node index.js"
}
| Field | Purpose | Example value |
|---|---|---|
watch |
Directories and files to monitor for changes | ["src", "index.js", ".env"] |
ext |
File extensions that trigger a restart | "js,json,env" |
ignore |
Paths that should never trigger a restart | ["node_modules", "*.test.js"] |
delay |
Milliseconds to wait after a change before restarting | 500 |
env |
Environment variables set for the process | { "NODE_ENV": "development" } |
exec |
Command to run (defaults to node) | "node index.js" |
Reading the nodemon Output
$ npm run dev
> mern-blog-server@1.0.0 dev
> nodemon index.js
[nodemon] 3.0.3
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**/* index.js .env
[nodemon] watching extensions: js,json,env
[nodemon] starting `node index.js`
MongoDB connected: cluster0.example.mongodb.net โ your startup logs
Server running on http://localhost:5000
--- [you save a file] ---
[nodemon] restarting due to changes...
[nodemon] starting `node index.js`
MongoDB connected: cluster0.example.mongodb.net
Server running on http://localhost:5000 โ restarted โ
--- [force a manual restart at any time] ---
rs โ type this in the terminal and press Enter
Advanced: Watching .env Changes
// nodemon.json โ restart when .env changes too
{
"watch": ["src", "index.js", ".env"],
"ext": "js,json,env",
"ignore": ["node_modules"]
}
Why this matters:
If you change MONGODB_URI or JWT_SECRET in .env while the server is running,
the change has NO effect until the server restarts.
dotenv reads .env once on startup โ it does not hot-reload.
With nodemon watching .env, saving .env automatically restarts the server
and picks up the new values.
Using nodemon with ES Modules
// If your server uses ES Modules ("type": "module" in package.json)
// nodemon still works โ just run it the same way:
{
"scripts": {
"dev": "nodemon index.js"
}
}
// nodemon detects the module type from package.json automatically
Common Mistakes
Mistake 1 โ Using nodemon in the production start script
โ Wrong โ nodemon in the start script that platforms like Render use in production:
"scripts": {
"start": "nodemon index.js" // nodemon is a devDependency โ missing in production!
}
โ Correct โ separate scripts for development and production:
"scripts": {
"start": "node index.js", // production
"dev": "nodemon index.js" // development only
}
Mistake 2 โ Watching node_modules
โ Wrong โ no ignore config causes nodemon to watch node_modules, triggering constant restarts when npm operations run:
nodemon watching path(s): *.* โ watching everything including node_modules
[nodemon] restarting... โ restarting every few seconds for no reason
โ Correct โ always add node_modules to the ignore list in nodemon.json:
{ "ignore": ["node_modules", "src/logs/*"] }
Mistake 3 โ Not installing nodemon locally, relying on global install
โ Wrong โ assuming everyone on the team has nodemon installed globally:
npm install -g nodemon # installs globally on YOUR machine
# Another developer clones the repo and runs: npm run dev
# Error: nodemon: command not found (not installed globally on their machine)
โ Correct โ install locally as a devDependency so it is always available via node_modules/.bin:
npm install -D nodemon # added to devDependencies in package.json
# Everyone who runs npm install gets nodemon automatically โ
Quick Reference
| Task | Command / Config |
|---|---|
| Install nodemon | npm install -D nodemon |
| Start with nodemon | npm run dev (via package.json script) |
| Force manual restart | Type rs + Enter in terminal |
| Watch extra file types | "ext": "js,json,env" in nodemon.json |
| Ignore a directory | "ignore": ["node_modules", "logs"] |
| Add restart delay | "delay": 500 in nodemon.json |
| Watch specific dirs only | "watch": ["src", "index.js"] |