Skip to content

Why Use nodemon Instead of Native Watch for Node.js?

Problem

I tried to switch from nodemon to native Node.js watch for my development server. But I quickly hit limitations.

Terminal window
user@host:~/project$ node --watch src/index.js
Server running on port 3000
[Error] Cannot find module './config.json'

When I changed a config file, the server crashed. Native watch restarted too fast, before my build process finished.

Environment

  • Node.js 20.10.0
  • TypeScript 5.3
  • Express server
  • Hot reload needed
  • Custom build step

What happened?

I removed nodemon and switched to native watch to reduce dependencies. Here’s my package.json:

"package.json
{
"scripts": {
"dev": "node --watch src/index.js
}
}

I can explain the key parts:

  • Native watch is built into Node.js 20+
  • No extra dependency needed
  • Simple configuration

But when I ran it, I got errors. Native watch restarted on every file change, including:

  • Transpiled files in dist/
  • Test files
  • Config files being written

This caused multiple restarts per second and crashed my server.

How to solve it?

I tried to add delays and ignore patterns, but native watch doesn’t support them:

Terminal window
# This doesn't work - no delay option
node --watch --delay 1000 src/index.js
# This doesn't work - no ignore option
node --watch --ignore dist src/index.js

So I went back to nodemon:

"package.json
{
"scripts": {
"dev": "nodemon
},
"nodemonConfig": {
"watch": ["src"],
"ext": "js,json",
"ignore": ["dist", "node_modules", "*.test.js"],
"delay": "1000
}
}

Now my server only restarts when I actually change source files.

Advanced nodemon features

I found nodemon has features native watch lacks:

Environment variables:

{
"nodemonConfig": {
"env": {
"NODE_ENV": "development",
"DEBUG": "app:*
}
}
}

Custom restart logic:

{
"scripts": {
"dev": "nodemon --exec 'npm run build && node dist/index.js'
}
}

Ignored file patterns:

{
"nodemonConfig": {
"ignore": [
"dist/**",
"*.test.js",
"*.spec.js",
"node_modules/**
]
}
}

The reason

I think the key reason for using nodemon:

  1. Ignore patterns: Don’t restart on test or build files
  2. Delay support: Wait for build processes to finish
  3. Custom exec: Run build steps before restart
  4. Environment management: Set different env vars per project
  5. Detailed logs: See exactly what changed and why

Native watch is great for simple scripts. But for real-world development, you need more control.

When to use each

Use native watch when:

  • Simple Node.js scripts
  • No build process
  • No complex dependencies
  • Want to reduce packages

Use nodemon when:

  • TypeScript or transpilation
  • Complex build steps
  • Multiple file types to ignore
  • Need restart delays
  • Custom restart logic

Summary

In this post, I showed why nodemon is still useful despite native watch. The key point is that professional development needs features like ignore patterns, delays, and custom restart logic that native watch doesn’t provide.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments