Using nodemon for Automatic Server Restart

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
Note: nodemon is only used during development. In production your server is started once and runs continuously โ€” there are no file changes to watch. This is why nodemon belongs in devDependencies and the production "start" script uses plain node index.js while the "dev" script uses nodemon index.js.
Tip: nodemon can restart on more than just JavaScript file changes. Use the --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.
Warning: nodemon restarts on every file save, including temporary saves, autosaves, and save-on-format (Prettier). If your server takes more than a second to start and connect to MongoDB, rapid successive saves can cause it to restart before the previous start completes, leading to confusing port-already-in-use errors. Use the 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"]

🧠 Test Yourself

You update a value in your server’s .env file but the Express server behaviour does not change. The server is running with nodemon. What is the most likely cause?