How to Configure a Nodemon Configuration File (nodemon.json) the Right Way

If you’ve used Node.js for more than five minutes, you’ve probably installed nodemon and enjoyed that tiny dopamine hit when your server reloads automatically after a file change. Then you hit the next stage: your project grows, your folder structure gets real, and suddenly nodemon is restarting too often, not restarting when it should, or restarting on changes you don’t care about.

That’s the moment a proper Nodemon configuration file becomes your best friend.

This guide walks through how to configure Nodemon using nodemon.json (and a couple of other approaches), with real-world examples you can copy into production-grade projects. We’ll also cover common edge cases: TypeScript, Express, monorepos, Docker, ignoring build folders, watching multiple directories, and passing Node flags cleanly.


Why Use a Nodemon Configuration File?

You can run nodemon with a long command like this:

nodemon --watch src --ext js,json --ignore dist --exec node src/server.js

…but that gets painful fast. A config file gives you:

Predictable dev startup commands, a shared setup for your team, fewer mistakes in scripts, and clean package.json scripts that are easy to read. In SEO terms: if you’re searching “how to configure nodemon”, “nodemon.json example”, “nodemon ignore dist”, or “nodemon watch src”, the config file is exactly what you want.


The Standard Way: Create nodemon.json

Nodemon looks for a config file named nodemon.json in your project root (same level as package.json). Create it like this:

{
  "watch": ["src"],
  "ext": "js,json",
  "ignore": ["node_modules", "dist"],
  "exec": "node src/index.js"
}

Now you can run:

nodemon

…and it will use your configuration automatically.

What Each Option Does (the practical explanation)

watch tells nodemon which directories or files should trigger a restart. Most projects want src, not the entire repo.

ext defines which file extensions nodemon cares about. If you only write JavaScript and JSON configs, "js,json" is enough. If you’re using TypeScript, add ts.

ignore prevents infinite restart loops and noisy reloads. This is where you ignore output folders like dist, logs, uploads, coverage, and anything generated.

exec is the command nodemon runs to start your app. This is the cleanest place to define “how to start my dev server.”


Best-Practice Nodemon Config for a Typical Express App

A lot of people want nodemon to restart on changes to backend code, but not restart when the build output changes. Here’s a solid configuration for an Express + Node project:

{
  "watch": ["src"],
  "ext": "js,json",
  "ignore": ["node_modules", "dist", "coverage", "*.log"],
  "exec": "node src/server.js",
  "delay": 200
}

That delay is subtle but important. Some editors save multiple files quickly, and a short delay prevents nodemon from restarting twice for one change.

If you’re seeing “nodemon keeps restarting” or “nodemon restart loop”, it’s almost always because you’re watching your build output or writing logs inside a watched folder.


Configure Nodemon for TypeScript

TypeScript changes the game because you have two common workflows:

Option A: Run TS directly with ts-node (fast setup)

Install:

npm i -D nodemon ts-node typescript

Then use this nodemon.json:

{
  "watch": ["src"],
  "ext": "ts,json",
  "ignore": ["node_modules", "dist"],
  "exec": "ts-node src/index.ts"
}

This is the simplest “nodemon + TypeScript” setup and works great for many apps.

Option B: Compile with tsc, run compiled output (closer to production)

If you compile to dist, you want nodemon to watch src and trigger a build, then run Node on dist.

Install TypeScript:

npm i -D nodemon typescript

Example nodemon.json:

{
  "watch": ["src"],
  "ext": "ts,json",
  "ignore": ["node_modules", "dist"],
  "exec": "npm run build && node dist/index.js",
  "delay": 300
}

This avoids ts-node runtime quirks and mirrors production more closely. The key is ignoring dist so nodemon doesn’t restart because it just wrote new build files.


Using Nodemon with Environment Variables

You’ll often want NODE_ENV=development or custom env vars. You have a few clean options:

Put env vars inside the exec command

{
  "watch": ["src"],
  "ext": "js,json",
  "exec": "NODE_ENV=development node src/index.js"
}

That works on macOS and Linux. For Windows compatibility, many teams prefer a cross-platform helper.

Cross-platform: use cross-env

Install:

npm i -D cross-env

Then:

{
  "watch": ["src"],
  "ext": "js,json",
  "exec": "cross-env NODE_ENV=development node src/index.js"
}

This is one of the most searched combinations for nodemon configuration because Windows users otherwise hit a wall.


Passing Node Flags (Inspect, Memory Limits, Warnings)

When you need debugging, the nodemon config is the right place to make it consistent across your team.

{
  "watch": ["src"],
  "ext": "js,json",
  "exec": "node --inspect=0.0.0.0:9229 src/index.js"
}

If you’re inside Docker or using remote debugging, binding 0.0.0.0 is what makes it accessible outside the container.


Fine-Tuning Restarts: ignore, watch, and “why is nodemon restarting?”

This is where most dev time gets wasted.

If nodemon restarts every time you hit an endpoint, you’re probably writing something to disk in a watched folder. Common culprits include request logs, file uploads, temp files, or generated JSON.

A defensive ignore list for real projects looks like this:

{
  "watch": ["src"],
  "ext": "js,json",
  "ignore": [
    "node_modules",
    "dist",
    "coverage",
    "uploads",
    "tmp",
    "*.log"
  ],
  "exec": "node src/index.js"
}

If you genuinely need to watch multiple folders (say you have a shared library folder), you can do it:

{
  "watch": ["src", "shared"],
  "ext": "js,json",
  "ignore": ["node_modules", "dist"],
  "exec": "node src/index.js"
}

Alternative Configuration Locations (and Who Should Use Them)

1) package.json nodemonConfig

You can configure nodemon in package.json under nodemonConfig. Example:

{
  "name": "my-app",
  "scripts": {
    "dev": "nodemon"
  },
  "nodemonConfig": {
    "watch": ["src"],
    "ext": "js,json",
    "ignore": ["dist"],
    "exec": "node src/index.js"
  }
}

This is convenient for smaller repos, but for medium and large apps I still prefer a dedicated nodemon.json so config changes are easy to spot and review.

2) CLI flags

Good for one-off experiments, not great for teams. People copy and paste the wrong command, and suddenly everyone’s dev environment is inconsistent.


Once nodemon.json exists, your scripts can stay wonderfully simple:

{
  "scripts": {
    "dev": "nodemon",
    "start": "node dist/index.js",
    "build": "tsc -p tsconfig.json"
  }
}

This separation is important. dev uses nodemon, start is what you run in production, and build is explicit. It also keeps your CI pipeline clean.


Nodemon in a Monorepo or Nested App Folder

If your Node app lives inside a subfolder like apps/api, you have two good patterns:

  1. Put nodemon.json inside apps/api and run nodemon from there.
  2. Keep nodemon in the root but point to a config file:

nodemon --config apps/api/nodemon.json

That second approach is a lifesaver when you’ve got multiple services and you want the root scripts to control everything.


Nodemon + Docker: The One Setting People Miss

Nodemon works in Docker, but file watching can be flaky depending on your host OS and volume setup. A commonly effective tweak is enabling legacy watching:

{
  "watch": ["src"],
  "ext": "js,json",
  "ignore": ["node_modules", "dist"],
  "exec": "node src/index.js",
  "legacyWatch": true
}

If you’re Googling “nodemon not restarting in docker”, this option is often the difference between frustration and a smooth workflow.


A Production-Grade nodemon.json Template You Can Copy

If you want a strong default that works for many Node backends, start here and adjust:

{
  "watch": ["src"],
  "ext": "js,json,ts",
  "ignore": [
    "node_modules",
    "dist",
    "coverage",
    ".git",
    "*.log",
    "tmp",
    "uploads"
  ],
  "delay": 250,
  "exec": "node src/index.js"
}

If you’re on TypeScript, replace the exec line with either ts-node src/index.ts or your build-and-run command. The rest stays useful across stacks.


Common Troubleshooting (Fast, Real Fixes)

If nodemon doesn’t restart, check that the file you edited matches your ext list and lives inside a watch directory. The “it doesn’t restart” problem is usually a watch scope issue, not nodemon being broken.

If nodemon restarts nonstop, check whether you are writing generated files into a watched folder. Add the generated folder to ignore, or move generated output to dist and ignore it.

If nodemon restarts twice, add or increase delay. Some editors do atomic saves that trigger multiple filesystem events.

If Windows is acting up with env vars, use cross-env inside exec, or move env loading into your app with something like dotenv and keep the nodemon command clean.


Final Take

Configuring Nodemon properly isn’t about fancy tooling, it’s about controlling the restart signal so your development loop stays fast and predictable. A solid nodemon.json in the project root, a careful ignore list, and a clean exec command will save you hours over the lifetime of a codebase.

If you’re building anything beyond a tiny demo, treat your Nodemon configuration file like part of your developer experience: version it, keep it readable, and make it boring. Boring here means reliable, and reliable is what ships.