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.
user@host:~/project$ node --watch src/index.jsServer 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:
{ "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:
# This doesn't work - no delay optionnode --watch --delay 1000 src/index.js
# This doesn't work - no ignore optionnode --watch --ignore dist src/index.jsSo I went back to nodemon:
{ "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:
- Ignore patterns: Don’t restart on test or build files
- Delay support: Wait for build processes to finish
- Custom exec: Run build steps before restart
- Environment management: Set different env vars per project
- 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