Choosing Between nodemon Default Mode and the --exec Flag
Decide between nodemon's default Node execution and the --exec flag. Compare performance trade-offs, avoid common spawn errors, and implement a shared nodemon.json config.
30 Jun 2026, 05:55 UTC

Decision: When to use nodemon's default mode versus --exec
If you are developing a plain JavaScript Node.js project, nodemon's default execution (nodemon app.js) provides the fastest restart by spawning the Node process directly. However, when your workflow requires a transpiler (such as Babel or TypeScript), a test runner, or a specific shell command to wrap the execution, you must use the --exec flag or the "exec" property in a nodemon.json configuration file.
Constraints and Prerequisites
- Path Availability: The command passed to
--execmust be available in the system'sPATH. If the executable cannot be found, nodemon will emit aspawn ENOENTerror and fail to start. - Process Lifecycle: Avoid using
--execwith commands that daemonize or start long-running background processes that do not exit. Nodemon relies on the child process terminating to manage the restart cycle; if the process does not exit, nodemon may fail to kill the old instance. - Environment: Use
--execwhen you need to inject environment variables or use shell-specific piping before the Node process begins.
Option Comparison
| Option | Mechanism | Best Use Case | Trade-off |
|---|---|---|---|
| Default Mode | Directly spawns node |
Standard .js/.mjs files | Fastest restart; no custom wrappers. |
| --exec Flag | Wraps command in a shell | Babel, ts-node, or one-off custom scripts | Flexible; adds slight shell overhead. |
| nodemon.json | Persistent config for --exec |
Team-shared projects with transpilers | Version-controlled; requires config file. |
Trade-off Analysis
The primary trade-off is startup latency versus flexibility. In default mode, nodemon bypasses the shell and invokes the Node binary directly, minimizing the gap between a file save and the application restart. Using --exec introduces a shell layer that must parse the command and locate the executable. While this adds a few milliseconds of overhead, it is the only way to integrate tools like babel-node or ts-node, which preprocess code before execution.
Implementation: Configuring nodemon.json for Transpilation
To ensure all developers on a project use the same execution wrapper, create a nodemon.json file in the project root:
{
"exec": "babel-node src/index.js",
"ext": "js jsx",
"watch": ["src"]
}
Execution: Run the following command in your terminal from the project root:
nodemon
Required Permissions: No special administrative permissions are required, provided the user has execution rights for the binary specified in the "exec" property.
Verification Steps
- Binary Check: Run
which babel-node(Unix) orwhere babel-node(Windows) to confirm the tool is in yourPATH. - Startup Log: Confirm the console output reads
[nodemon] starting `babel-node src/index.js`. - Trigger Restart: Modify a file within the
src/directory. Observe the console for the restart event. - PID Validation: To verify a clean restart, add
console.log(`Process ID: ${process.pid}`);to your entry file. Confirm that the PID changes after every file save.
Limitations and Diagnostics
If you encounter an ENOENT error, it typically means the command in "exec" is installed locally in node_modules/.bin but not globally. To resolve this, you can either use the full path to the binary or run nodemon via an npm script in package.json, which automatically adds local binaries to the path:
"scripts": {
"dev": "nodemon"
}
To practically measure the overhead of --exec, use console.time('boot') at the very top of your script and console.timeEnd('boot') after initializations. Compare the results between default mode and --exec mode to see the impact of the wrapper and transpiler.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.