Alexander Nnakwue Software engineer. React, Node.js, Python, and other developer tools and libraries.

Nodemon tutorial: Automatically restart Node.js apps with Nodemon

8 min read 2431

Introduction

In development environments, especially those that involve lots of iterations, we do not want to restart our server or backend app manually when we make changes to our source code.

This is an issue that Nodemon solves. It acts as a utility library for keeping track of server changes and automatically restarts our app for us.

According to the documentation, Nodemon is a perfect tool for development in Node.js-based applications. Indeed, it was built with the properties of the Node’s CLI command in mind, since it is a wrapper around the node command.

Basically, it works by detecting changes in the current directory of our source code, and restarts the server to cater to these new changes.

Recall that in order to run a Node.js app, we begin with the node command and append the file name. In development with Nodemon, all we need to do is run Nodemon filename, and Nodemon will watch our files for us.

However, to make use of Nodemon, we need to install it globally on our machines or locally on a per-project basis.

When installed on a per-project basis, all we need to do is update the script tag in the package.json file of our project. To use Nodemon in development mode, we can add a "dev": "nodemon app.js" line to the script tag in the same file.

When installed globally, Nodemon is available on our system path and works out of the box.

In this tutorial, I will explain how Nodemon works by exploring its features and how they are being used.

We will cover the following:

We made a custom demo for .
No really. Click here to check it out.

  • What is Nodemon?
  • Installing Nodemon both locally and globally
  • Nodemon configurations and usage
  • Nodemon’s features

In order to follow along with this tutorial, readers should have a basic understanding of Node.js and Express.

What is Nodemon?

As I earlier mentioned, Nodemon is a utility or a helper tool that watches for file changes and automatically restarts our Node.js applications. It is open source, well maintained, and used by lots of people in the community.

To see a list of available Nodemon commands, we can use the -h flag or the --help flag shown below. So we can either run:

nodemon -h 
 //or 
nodemon --help

There are several reasons why we should use Nodemon in developing Node.js based applications.

Firstly, it is very easy to set up. Secondly, once it is installed, it runs automatically, as it doesn’t require any instance to call, and lastly, it aids faster iterations for development environments.

Now, let’s explore how we can install Nodemon below.

Installing Nodemon

As we earlier mentioned, Nodemon can either be installed globally on our system path, or locally as a development dependency.

To install Nodemon globally on our path, we can go ahead and run the command below with the global -g flag:

npm install -g nodemon

This means that the package can be used and run from the system path on our development machine.

Otherwise, we can run:

npm install --save-dev nodemon

The above command will install Nodemon locally on our machine or as a development dependency. Note here that we are installing Nodemon as a development dependency with the --save-dev flag, as we do not want it as a production dependency.

When Nodemon is installed globally, we do not need to do any other setup on our local environment as we can run Nodemon from any path on our system and it will watch our source files for us.

After running the above command, our package.json file will be modified and the Nodemon library with its version number will be saved under the key "devDependencies" as shown below:

{
  "name": "test-app",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
}
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  }
{
  "author": "",
  "license": "ISC",
  "private": false,
  "devDependencies": {
    "nodemon": "^2.0.7"
  },
 }

As a development dependency, all we need to do is add a dev script in our package.json file to be able to use Nodemon in our local setup. Let us now proceed by displaying a simple Node.js application to understand all the features and configuration options for Nodemon.

Let’s start small with the server setup located in the app.js file. The contents of that file is shown below:

require('dotenv').config()
require('./mongoClient')

const express = require('express')
const config = require('./config')
const routes = require('./routes')
const app = express()

// add routes here
routes(app)

// catch 404 and forward to error handler
app.use((req, res, next) => {
    const err = new Error('Not Found')
    console.log(err)
    err.status = 404
    res.send('Route not found')
    next(err)
})

app.listen(process.env.PORT || config.port, () => {
    console.log(`${config.appName} listening on port ${config.port}!`)
})

module.exports = app

Let us also have a look at how to run this server file using Nodemon. The very basic and minimal setup for making use of Nodemon in our project is shown below in the package.json file located in the root:

{
  "name": "nodemon_tutorial",
  "version": "1.0.0",
  "description": "A Tutorial for Understanding Nodemon",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "directories": {
    "model": "model",
    "controllers": "controllers"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [
    "Node.js",
    "JavaScript"
  ],
  "author": "Alexander Nnakwue",
  "license": "MIT",
  "devDependencies": {
    "nodemon": "^2.0.4"
  },
  "dependencies": {
    "bcrypt": "^5.0.1",
    "debug": "^4.1.1",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "express-async-handler": "^1.1.4",
    "mongoose": "^5.9.25",
    "mongoose-paginate": "^5.0.3",
    "path": "^0.12.7",
    "uuidv4": "^6.2.0"
  },
  "engines": {
    "node": "13.7.0",
    "npm": "6.13.6"
  }
}

As we can see from the setup in the scripts tag below:

"scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },

So when we run npm run dev, it runs Nodemon and watches our files for us.

The content when we run the file with Nodemon is shown below:

[nodemon] clean exit - waiting for changes before restart
[nodemon] restarting due to changes...
[nodemon] starting `node app.js`
(node:97775) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Nodemon_tutorial listening on port 5000!
mongodb connected
Mongoose: users.createIndex({ email: 1 }, { unique: true, background: true })
Mongoose: users.createIndex({ phoneNumber: 1 }, { unique: true, background: true })

Any output from this script is prefixed with [nodemon], otherwise all output from your application, errors included, will be echoed out as expected.

With the --inspect flag (useful for a Node.js process listening for a debugger) in the package.json file, the output when we run npm run dev is shown below:

[email protected] backend-server % npm run dev

> [email protected] dev /Users/retina/Dropbox/My Mac (alexander)/Desktop/nodemon_tutorial/nodemon_tutorial
> nodemon --inspect app.js

[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node --inspect app.js`
Debugger listening on ws://127.0.0.1:9229/8618d563-210c-4070-bed5-b077016abae2
For help, see: https://nodejs.org/en/docs/inspector
(node:98970) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Nodemon_tutorial listening on port 5000!

As of version 1.1.x, Nodemon will search for a scripts.start property or a main property in the package.json file in the current working directory and start the app for us.

Let’s try this out:

(aba) [email protected] backend-server % nodemon
[nodemon] 2.0.7
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `node app.js`
(node:99661) ExperimentalWarning: Conditional exports is an experimental feature. This feature could change at any time
Nodemon_tutorial listening on port 5000!
mongodb connected
Mongoose: users.createIndex({ email: 1 }, { unique: true, background: true })
Mongoose: users.createIndex({ phoneNumber: 1 }, { unique: true, background: true }) 

As we can see from the above, our app still works as it should. Note that here, I have deleted the scripts property from the package.json file and rerun the app with just the nodemon command:

// delete the script tag and run nodemon afresh
"scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  }

For this to work, we needed to have nodemon globally installed in our system path. The output when we run the command npm i nodemon -g to install Nodemon globally is shown below:

[email protected] ~ % npm i nodemon -g
/usr/local/bin/nodemon -> /usr/local/lib/node_modules/nodemon/bin/nodemon.js

> [email protected] postinstall /usr/local/lib/node_modules/nodemon
> node bin/postinstall || exit 0

+ [email protected]
added 120 packages from 57 contributors in 13.404s

Nodemon configurations and usage

Nodemon supports both local and global configurations the same way we can configure the system globally or on a per-project basis.

For a local setup, we can have a nodemon.json file in the current working directory of our project, and for a global setup, we can have the same file in our system’s home path.

Also, we can set up a nodemonConfig in the projects package.json file for those who prefer to keep all their package configurations in a single place.

Note that these configurations come with a caveat when it comes to which ones are executed. If we specify a --config file or provide a local nodemon.json file, any package.json config is ignored.

As you may have noticed, there are three ways of configuring Nodemon for development – local, global, and via the Node CLI. When we type nodemon --help options, we get to see all the available CLI options for our use.

For more info on available ways to configure Nodemon, we can also type *nodemon --help config* on our terminal.

Typically the options to control Nodemon are passed in via the CLI and can be listed when we run nodemon --help option.

Now, let’s examine some of the several configurations that we can add by passing more parameters to a configuration(--config) file or to our nodemon.json file. Some of these configurations might be useful while developing our projects. Let’s take a look at some of them below.

Monitoring multiple directories

Nodemon by default monitors the current working directory, but this can be altered by using the --watch option to add specific paths.

For instance, we can instruct Nodemon to only watch for changes in our services directory or in the app.js file in the nodemon_tutorial directory by running the command below:

nodemon --watch nodemon_tutorial/app.js --watch services 

Always add a --watch flag for each directory we intend to watch. This usually is required when multiple directories are passed.

Ignoring files

Since Nodemon by default restarts a web server when there are file changes, we can effectively change this default setting by configuring Nodemon to ignore changes made in some specific files, directories, or file patterns via the command line.

See an example below where we ignore the tests folder:

nodemon --ignore tests/ 

The above command, when run, will automatically ignore any changes made in the tests folder. Also, note that by default Nodemon ignores files in the node_modules and .git folder. Amazing right? Let’s move on.

Delaying restart

The default timeout to check for new file changes is usually about one second. However, there are cases where we intend to delay the time it takes for Nodemon to check for file changes for a longer period.

We can do this by using the --delay command. See the code sample below:

nodemon --delay 3000ms index.js  

3000ms is the delay value in milliseconds (this could also be in seconds) before our app restarts. Therefore, Nodemon will only restart the web server when that time elapses.

Extensions to watch

We can specify extensions to watch when there are file changes in directories or sub directories.

For example, we can specify our own list with the -e (or --ext) command line argument. See the code sample below:

nodemon -e njk

By default, Nodemon looks for files with the .js, .mjs, .coffee, .litcoffee, and .json extensions.

Running non-Node code

Apart from Node programs, Nodemon can also be used to monitor other programs. Based on the file extension, Nodemon will go ahead to execute the command.

For more details on running non-Node code, readers can check the documentation.

While Nodemon is running, we can manually restart our application. So instead of stopping and restarting Nodemon, we can just type rs and press enter, and Nodemon will restart the server or the running process for us.

Features of Nodemon

Piping output to a file (or anywhere else)

We can tell Nodemon not to write to the stdout by specifying a set of rules to do so. More details can be found in the documentation.

Adding default executables

Nodemon, with the help of the nodemon.json config file, can have a default executable declared. This will in turn allow us watch for changes that are not node.js specific.

To do so, we can make use of the execMap property. Note that it is generally recommended to use the global nodemon.json to add an execMap option to our config. You can read more details in the documentation.

Triggering events on state change

We can add a notification when Nodemon restarts. Also, an action can be triggered when an event occurs. More details about this can be found in the documentation.

Usable as a module

As of version 1.0.0, Nodemon can work as a required module in Node.js. By doing this, we can then extend its functionality and make it suit our other needs.

More details can be found in the documentation here.

Conclusion

In Node.js, Nodemon can be likened to a magic wand because of its ability to automatically restart a web application upon file changes. In other words, Nodemon simply eliminates the need for programmers to manually stop and restart their application source code in development repeatedly after every change is made.

It is a utility tool that makes rapid development less cumbersome. As a tool, it continuously monitors your Node.js application and quietly waits for file changes before automatically restarting the server. To add some more extra configurations, we can make use of a nodemon.json file.

The file can be used to add some extra configurations to our application to allow us monitor multiple directories, ignore files, and delay restarting amongst others. For more details and “gotchas” on how Nodemon works and possible work arounds for issues, readers can also refer to the FAQ.

The FAQ documentation also contains some other tips and tricks we can refer to, including other use cases for Nodemon not mentioned or covered in this tutorial.

For example, clearing the console on restart, restarting Nodemon on .env file change, overriding the default ignore rules, and so on. A link to the documentation is available here on GitHub.

Thanks again for reading. Please drop any comments or questions you have in the comment section below, or reach out to me on Twitter.

200’s only Monitor failed and slow network requests in production

Deploying a Node-based web app or website is the easy part. Making sure your Node instance continues to serve resources to your app is where things get tougher. If you’re interested in ensuring requests to the backend or third party services are successful, try LogRocket. https://logrocket.com/signup/

LogRocket is like a DVR for web apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic network requests to quickly understand the root cause.

LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. .
Alexander Nnakwue Software engineer. React, Node.js, Python, and other developer tools and libraries.

Leave a Reply