582

How could I implement an auto-reload of files in Node.js? I'm tired of restarting the server every time I change a file.

Apparently, Node.js' require() function does not reload files if they have already been 'required', so I need to do something like this:

var http    = require('http'),
    posix   = require('posix'),
    json    = require('./json');

var script_name = '/some/path/to/app.js';
this.app = require('./app').app;

process.watchFile(script_name, function(curr, prev){
    posix.cat(script_name).addCallback(function(content){
        process.compile( content, script_name );
    });
});

http.createServer(this.app).listen( 8080 );

And in the app.js file I have:

var file = require('./file');
this.app = function(req, res) {
    file.serveFile( req, res, 'file.js');
}

But this also isn't working. I get an error in the process.compile() statement, saying that 'require' is not defined. process.compile is eval'ing the app.js, but it doesn’t have any clue about the Node.js globals.

3
  • 5
    You know you can just run this code on each request: Object.keys(require.cache).forEach(function(key) { delete require.cache[key]; }); Commented Jul 21, 2012 at 18:55
  • 1
    See strongloop.com/strongblog/… Commented Aug 8, 2014 at 16:48
  • Why do you have two js files, app.js as a server file should be enough? Commented Mar 6, 2021 at 6:49

32 Answers 32

828

A good, up-to-date, alternative to supervisor is nodemon:

Monitor for any changes in your node.js application and automatically restart the server - perfect for development

To use nodemon with version of Node.js without npx (v8.1 and below, not advised):

npm install nodemon -g
nodemon app.js

Or to use nodemon with versions of Node.js with npx bundled in (v8.2+):

npm install nodemon
npx nodemon app.js

Or as devDependency in with an npm script in package.json:

"scripts": {
  "start": "nodemon app.js"
},
"devDependencies": {
  "nodemon": "..."
}
Sign up to request clarification or add additional context in comments.

10 Comments

and if you want to use it in Nitrous.io -- $ nodemon -L yourfile.js (full explanation at coderwall.com/p/aqxl_q)
But in this case, it restart the server process as well.
automatically restart the server - perfect for development is way too much hyperbole. Reloading server could mean logging into backend services which does take a long time in my case. "Perfect for development" would be something like hot-reloading classes while process is running in memory without losing state a-la what android studio does when you change source code.
use npm install [--save-dev | -D] nodemon to limit the installation to project scope.
This only restarts the server, the web clients would still need to be manually reloaded.
|
326

node-supervisor is awesome.

Usage to restart on save for old Node.js versions (not advised):

npm install supervisor -g
supervisor app.js

Usage to restart on save for Node versions that come with npx:

npm install supervisor
npx supervisor app.js

Or directly call supervisor in an npm script:

"scripts": {
  "start": "supervisor app.js"
}

9 Comments

npm install -g supervisor. It should be installed globally.
Had to run it like this under Windows: "C:\Program Files\nodejs\node.exe" C:\Users\Mark\AppData\Roaming\npm\node_modules\supervisor\lib\cli-wrapper.js app.js
without -g or sudo at app root: npm install supervisor, node node_modules/supervisor/lib/cli-wrapper.js app.js (I have a non-root installation of Node)
@Mark This means node is not in your PATH
Note that this is very much not what the question was about though. Restarting is the exact opposite of hot-reloading.
|
107

I found a simple way:

delete require.cache['/home/shimin/test2.js']

7 Comments

This is great if you want to reload external libraries without restarting the app--in my case, an IRC bot.
This is excellent! So simple and works so well. Whenever a request comes in I just uncache a bunch of files that don't hold state.
delete require.cache[require.resolve('./mymodule.js')]; resolve deal with real paths
Is this safe to do or considered "bad practice" or "development only"?
@jocull I don't think it's safe, since it may recreate classes and functions or whatever exports, resulting in different references when comparing with ===
|
45

Nodemon has been the go to for restarting server for file changes for long time. Now with Node.js 19, they have introduced a --watch flag, which does the same [experimental]. Documentation

node --watch index.js

1 Comment

This works good with the latest LTS version of node (20.15.1 at the time of writing). Only thing missing is refreshing the browser so the changes are "instant"
27

If somebody still comes to this question and wants to solve it using only the standard modules, I made a simple example:

var process = require('process');
var cp = require('child_process');
var fs = require('fs');

var server = cp.fork('server.js');
console.log('Server started');

fs.watchFile('server.js', function (event, filename) {
    server.kill();
    console.log('Server stopped');
    server = cp.fork('server.js');
    console.log('Server started');
});

process.on('SIGINT', function () {
    server.kill();
    fs.unwatchFile('server.js');
    process.exit();
});

This example is only for one file (server.js), but it can be adapted to multiple files using an array of files, a for loop to get all file names, or by watching a directory:

fs.watch('./', function (event, filename) { // sub directory changes are not seen
    console.log(`restart server`);
    server.kill();
    server = cp.fork('server.js');
})

This code was made for Node.js 0.8 API, and it is not adapted for some specific needs, but it will work in some simple applications.

This functional is implemented in my module, simpleR, GitHub repository.

3 Comments

This is a great and simple solution. I just used it for a bot that was supposed to update itself from git when told so by a moderator. The problem was that once you're inside the app you can't restart yourself. I can, however, use your method to spawn an instance of the bot and watch a dotfile. The bot then updates itself, touches the dotfile, and will be automatically restarted by the launcher. Awesome!
@Fred i'm glad to hear this :) I will implement this solution in a module, soon I guess, I have some more ideas how to expand its functionality
If file watch is not needed, reload can be done without fs, by listening different signal.
20

nodemon came up first in a Google search, and it seems to do the trick:

npm install nodemon -g
cd whatever_dir_holds_my_app
nodemon app.js

Comments

12

nodemon is a great one. I just add more parameters for debugging and watching options.

File package.json:

  "scripts": {
    "dev": "cross-env NODE_ENV=development nodemon --watch server --inspect ./server/server.js"
  }

The command: nodemon --watch server --inspect ./server/server.js

Whereas:

--watch server Restart the app when changing .js, .mjs, .coffee, .litcoffee, and .json files in the server folder (included subfolders).

--inspect Enable remote debug.

./server/server.js The entry point.

Then add the following configuration to launch.json (Visual Studio Code) and start debugging anytime.

{
    "type": "node",
    "request": "attach",
    "name": "Attach",
    "protocol": "inspector",
    "port": 9229
}

Note that it's better to install nodemon as development dependency of the project. So your team members don't need to install it or remember the command arguments; they just npm run dev and start hacking.

See more on nodemon documentation: nodemon

3 Comments

Globbing is not supported for recent versions of nodemon (1.19.0 at least). Simply use nodemon --watch server --inspect ./server/server.js instead.
Thanks @Alex for your information. Updated the answer.
is there a way to rebuild the app with a rebuild for any changes to any client-side files in the react app?
9

With Node.js 19, you can monitor file changes with the --watch option. After a file is changed, the process is restarted automatically, reflecting new changes.

node --watch server.js

Comments

8

You can use nodemon from NPM. And if you are using Express generator then you can using this command inside your project folder:

nodemon npm start

or using Debug mode

DEBUG=yourapp:* nodemon npm start

you can also run directly

nodemon your-app-file.js

Hope this help.

3 Comments

this works on Windows if you type set DEBUG=myapp:* & nodemon npm start
I also had to follow these instructions to install nodemon globally stackoverflow.com/a/40359656/74585
I used express generator and nodemon npm start really worked, thanks
8

There is Node-Supervisor that you can install by

npm install supervisor

See node-supervisor.

2 Comments

It's more about restarting the server if it crashes. node-supervisor also restarts the whole process when watched files have been changed. It is not hot-reload in the strict sense.
Although not really hot-loading, this tool is really useful if you just want the code to autoreload while you're developing so you don't have to restart node in the command line after every change.
8

node-dev works great:

npm install node-dev

It even gives a desktop notification when the server is reloaded and will give success or errors on the message.

Start your application on a command line with:

node-dev app.js

Comments

6

There was a 2009 thread about this subject on the Node.js mailing list. The short answer is no; it's currently not possible autoreload required files, but several people have developed patches that add this feature.

1 Comment

+1 Yes. I participated in the discussion. I admitted that my solution is too simple. It only works if the hot module itself does not require further modules. Felix' solution is more well thought-out but it is debated if auto-reload really belongs to the core.
4

Yet another solution for this problem is using forever:

Another useful capability of Forever is that it can optionally restart your application when any source files have changed. This frees you from having to manually restart each time you add a feature or fix a bug. To start Forever in this mode, use the -w flag:

forever -w start server.js

2 Comments

Strangely with the -w flag my express.js app doesn't use CSS.
'forever' is not recognized as an internal or external command, operable program or batch file.
3

There is a solution at: Node.js hot reload of JavaScript files (it is not a restart, more like Erlang)

Notice that you have to take care by yourself of the references used.

That means if you did var x=require('foo'); y=x;z=x.bar; and hot reloaded it.

It means you have to replace the references stored in x, y and z. In the hot reload callback function.

Some people confuse hot reload with auto restart. My nodejs-autorestart module also has upstart integration to enable auto start on boot.

If you have a small application, auto restart is fine, but when you have a large application, hot reload is more suitable. Simply because hot reload is faster.

I also like my node-inflow module.

2 Comments

That's a nice one!
this is old one sorry
3

I am working on making a rather tiny Node.js "thing" that is able to load/unload modules at will (so, i.e., you could be able to restart part of your application without bringing the whole application down).

I am incorporating a (very stupid) dependency management, so that if you want to stop a module, all the modules that depends on that will be stopped too.

So far so good, but then I stumbled into the issue of how to reload a module. Apparently, one could just remove the module from the "require" cache and have the job done. Since I'm not keen to change directly the Node.js source code, I came up with a very hacky-hack that is: search in the stack trace the last call to the "require" function, grab a reference to it's "cache" field and...well, delete the reference to the node:

var deleteCache = function(moduleFullpathAndExt) {
  delete( require.cache[ moduleFullpathAndExt ] )
}

Apparently, this works just fine. I absolutely don’t have any idea of what that arguments["1"] means, but it's doing its job. I believe that the Node.js guys will implement a reload facility someday, so I guess that for now this solution is acceptable too.

(By the way, my "thing" will be here: Wirez: Runtime management of module dependencies for Node.js. Go there in a couple of weeks and you should see what I'm talking about)

3 Comments

..of course is not that simple. That only works if there is a call to require in the call stack. Oh well, easy hack on top of an hack: write that stuff in a temp script, and require it at runtime. Did it, it works..and it even clean itself from the cache
And actually it was easier: delete( require.cache[moduleFullpathAndExt] )
Node.js modules are actually wrapped in an anonymous function which is how the module encapsulation is done. Each module actually looks like function (module, require) { /* your code */ }. When you take this into account, arguments[1] points at require. And the while loop is there for situations where you call this from within another function in a module (it simply goes up the function hierarchy and checks the argument values passed to each).
3

Here is a blog post about hot reloading for Node.js. It provides a GitHub Node.js branch that you can use to replace your installation of Node.js to enable hot reloading.

From the blog post:

var requestHandler = require('./myRequestHandler');

process.watchFile('./myRequestHandler', function () {
  module.unCacheModule('./myRequestHandler');
  requestHandler = require('./myRequestHandler');
}

var reqHandlerClosure = function (req, res) {
  requestHandler.handle(req, res);
}

http.createServer(reqHandlerClosure).listen(8000);

Now, any time you modify myRequestHandler.js, the above code will notice and replace the local requestHandler with the new code. Any existing requests will continue to use the old code, while any new incoming requests will use the new code. All without shutting down the server, bouncing any requests, prematurely killing any requests, or even relying on an intelligent load balancer.

2 Comments

The only thing with this solution is that it's a fork of an older version of Node, so it will have to be tweaked and merged with the latest version before using (unless you don't mind using an older version of Node).
The blog.romeda.org link is broken: "Not Found. The requested URL was not found on this server. Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request."
2

You can do it with browser-refresh. Your node app restarts automatically, your result page in browser also refreshes automatically. Downside is that you have to put js snippet on generated page. Here's the repo for the working example.

const http = require('http');
const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
    res.statusCode = 200;
    res.setHeader('Content-Type', 'text/html; charset=UTF-8');
    res.write('Simple refresh!');
    res.write(`<script src=${process.env.BROWSER_REFRESH_URL}></script>`);
    res.end();
})

server.listen(port, hostname, () => {
    console.log(`Server running at http://${hostname}:${port}/`);

    if (process.send) {
        process.send({ event: 'online', url: `http://${hostname}:${port}/` })
    }

});

Comments

2

Here's a low tech method for use in Windows. Put this in a batch file called serve.bat:

@echo off

:serve
start /wait node.exe %*
goto :serve

Now instead of running node app.js from your cmd shell, run serve app.js.

This will open a new shell window running the server. The batch file will block (because of the /wait) until you close the shell window, at which point the original cmd shell will ask "Terminate batch job (Y/N)?" If you answer "N" then the server will be relaunched.

Each time you want to restart the server, close the server window and answer "N" in the cmd shell.

Comments

2

My app structure:

NodeAPP (folder)
   |-- app (folder)
      |-- all other files are here
   |-- node_modules (folder)
   |-- package.json
   |-- server.js (my server file)

First install reload with this command:

npm install [-g] [--save-dev] reload

Then change package.json:

"scripts": {
    "start": "nodemon -e css,ejs,js,json --watch app"
}

Now you must use reload in your server file:

var express = require('express');
var reload = require('reload');
var app = express();

app.set('port', process.env.PORT || 3000);

var server = app.listen(app.get('port'), function() {
    console.log( 'server is running on port ' + app.get('port'));
});

reload(server, app);

And for the last change, end of your response, send this script:

<script src="/reload/reload.js"></script>

Now start your app with this code:

npm start

3 Comments

This approach doesn't work, however, the ones led out in npmjs.com/package/reload (for Express apps) do.
This method works well and I use this method in a project that you can see in this path: github.com/KasraK2K/imensite-tutorial-site
The reload(server, app); is wrong, you have to change to reload(server);. In your code on github, you got it. Furthermore, I get an error error TS7016: Could not find a declaration file for module 'reload' and will open an issue because of typescript.
1

I have tried pm2 : installation is easy and easy to use too; the result is satisfying. However, we have to take care of which edition of pm2 that we want. pm 2 runtime is the free edition, whereas pm2 plus and pm2 enterprise are not free.

As for Strongloop, my installation failed or was not complete, so I couldn't use it.

Comments

1

It is not necessary to use nodemon or other tools like that. Just use the capabilities of your IDE.

Probably the best one is IntelliJ WebStorm with the hot reload feature (automatic server and browser reload) for Node.js.

Comments

1

If you’re talking about server-side Node.js hot-reloading, let’s say you wish to have a JavaScript file on the server which has an express route described and you want this JavaScript file to hot reload rather than the server restarting on file change then razzle can do that.

An example of this is basic-server.

The file server.js will hot-reload if it is changed and saved, the server does not restart.

This means you can program a REST server which can hot-reload using this razzle.

Comments

1

It's quite simple to just do this yourself without any dependency... the built-in file watcher have matured enough that it dose not sucks as much as before.

You don't need any complicated child process to spawn/kill and pipe std to in/out... You just need a simple web worker; that's all! A web Worker is also what i would have used in browsers too... so stick to web techniques! Worker will also log to the console.

import { watch } from 'node:fs/promises'
import { Worker } from 'node:worker_threads'

let worker = new Worker('./app.js')

async function reloadOnChange (dir) {
  const watcher = watch(dir, { recursive: true })
  for await (const change of watcher) {
    if (change.filename.endsWith('.js')) {
      worker.terminate()
      worker = new Worker('./app.js')
    }
  }
}

// All the folder to watch for
['./src', './lib', './test'].map(reloadOnChange)

This might not be the best solution where you use anything else other than JavaScript and do not depend on some build process.

Comments

0

Use this:

function reload_config(file) {
  if (!(this instanceof reload_config))
    return new reload_config(file);
  var self = this;

  self.path = path.resolve(file);

  fs.watchFile(file, function(curr, prev) {
    delete require.cache[self.path];
    _.extend(self, require(file));
  });

  _.extend(self, require(file));
}

All you have to do now is:

var config = reload_config("./config");

And config will automatically get reloaded :)

1 Comment

Got a version that doesn't rely on a framework that isn't part of Node?
0

loaddir is my solution for quick loading of a directory, recursively.

can return

{ 'path/to/file': 'fileContents...' } or { path: { to: { file: 'fileContents'} } }

It has callback which will be called when the file is changed.

It handles situations where files are large enough that watch gets called before they're done writing.

I've been using it in projects for a year or so, and just recently added promises to it.

Help me battle test it!

https://github.com/danschumann/loaddir

Comments

0

You can use auto-reload to reload the module without shutdown the server.

install

npm install auto-reload

example

data.json

{ "name" : "Alan" }

test.js

var fs = require('fs');
var reload = require('auto-reload');
var data = reload('./data', 3000); // reload every 3 secs

// print data every sec
setInterval(function() {
    console.log(data);
}, 1000);

// update data.json every 3 secs
setInterval(function() {
    var data = '{ "name":"' + Math.random() + '" }';
    fs.writeFile('./data.json', data);
}, 3000);

Result:

{ name: 'Alan' }
{ name: 'Alan' }
{ name: 'Alan' }
{ name: 'Alan' }
{ name: 'Alan' }
{ name: '0.8272748321760446' }
{ name: '0.8272748321760446' }
{ name: '0.8272748321760446' }
{ name: '0.07935990858823061' }
{ name: '0.07935990858823061' }
{ name: '0.07935990858823061' }
{ name: '0.20851597073487937' }
{ name: '0.20851597073487937' }
{ name: '0.20851597073487937' }

Comments

0

I recently came to this question because the usual suspects were not working with linked packages. If you're like me and are taking advantage of npm link during development to effectively work on a project that is made up of many packages, it's important that changes that occur in dependencies trigger a reload as well.

After having tried node-mon and pm2, even following their instructions for additionally watching the node_modules folder, they still did not pick up changes. Although there are some custom solutions in the answers here, for something like this, a separate package is cleaner. I came across node-dev today and it works perfectly without any options or configuration.

From the Readme:

In contrast to tools like supervisor or nodemon it doesn't scan the filesystem for files to be watched. Instead it hooks into Node's require() function to watch only the files that have been actually required.

Comments

0
const cleanCache = (moduleId) => {
    const module = require.cache[moduleId];
    if (!module) {
        return;
    }
    // 1. clean parent
    if (module.parent) {
        module.parent.children.splice(module.parent.children.indexOf(module), 1);
    }
    // 2. clean self
    require.cache[moduleId] = null;
};

Comments

0

Another simple solution is to use fs.readFile instead of using require. You can save a text file containing a JSON object, and create a interval on the server to reload this object.

Pros:

  • There isn’t any need to use external libraries
  • relevant for production (reloading a configuration file on change)
  • easy to implement

Cons:

  • you can't reload a module, just a JSON file containing key-value data

Comments

0

If you want to "restart everything" then the top-voted answers are fine, but if you're using Node.js in 2025 and you want to hot reload your module code those solutions are completely useless.

Instead, you're going to have to slightly change how you work with objects so that you can use dynamic imports (i.e., the import() function, not the import keyword) to update your already instantiated objects.

I've documented this extensively over on Flying planes with JavaScript, Hot-reloading to make our dev lives easier, but repeating it here:

We can set up a file watcher that uses "cache busting", because you can't unload modules the same way you can clear the legacy require cache:

// We'll be using Node.js' own file watch mechanism for this:
import { watchFile } from "node:fs";

// With some helpers for making sure we know where our files and modules live:
import { __root } from "./constants.js";
import { rootRelative } from "./utils.js";

export async function watch(basePath, modulePath, onChange) {
  const filePath = basePath + modulePath;
  const moduleURL = `file:///${filePath}`;

  // Step 1: don't run file-watching in production. Obviously.
  if (process.env.NODE_ENV === `production`) {
    return import(moduleURL);
  }

  // Next, get the current callstack, so we can report on
  // that when a file change warrants an update.
  const callStack = new Error().stack
    .split(`\n`)
    .slice(2)
    .map((v) => {
      return v
        .trim()
        .replace(`file:///${__root}`, `./`)
        .replace(/^at /, `  in `)
        .replace(/new (\S+)/, `$1.constructor`);
    })
    .join(`\n`)
    .replace(/\.constructor \(([^)]+)\)(.|[\n\r])*/, `.constructor ($1)`);

  // If we're not running in production, check this file for changes every second:
  watchFile(filePath, { interval: 1000 }, async () => {
    console.log(`Reloading module ${rootRelative(filePath)} at ${Date.now()}`);

    try {
      // If there was a change, reimport this file as an ES module, with a "cache busting" URL
      // that includes the current time stamp. Modules are cached based on their exact URL,
      // so adding a query argument that we can vary means we can "reimport" the code:
      const module = await import(`${moduleURL}?ts=${Date.now()}`);

      // Then we log the stack so we know where this reload was set up in our code:
      console.log(callStack);

      // To confirm to ourselves that a module was fully loaded as a "new module" we check
      // whether it has a `LOAD_TIME` constant that it set during load, and log what that
      // value is. Because it should be very close to our reload time.
      if (module.LOAD_TIME)
        console.log(`  Module-indicated load time is ${module.LOAD_TIME}`);

      // And then we run whatever code needs to run now that the module's been reloaded.
      onChange(module);
    } catch (e) {
      // Never crash the server just because someone saved a file with a typo.
      console.error(`\nWatcher could not load module: ${filePath}`);
      console.error(callStack);
      console.error(e);
    }
  });

  // Then, as part of the call, run an immediate load with a timestamp, so we're cache-busting.
  return import(`${moduleURL}?ts=${Date.now()}`);
}

Of course you can house those constants and utils imports however you like, but their associated code is:

// Get the directory that this file lives in:
import url from "node:url";
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));

// And then use that to figure out what the project root dir is:
import { join, resolve, sep, win32, posix } from "node:path";
export const __root = (resolve(join(__dirname, `..`, `..`)) + sep).split(win32.sep).join(posix.sep);

and

import { win32, posix } from "node:path";

// Get a file's path relative to the project root directory
export function rootRelative(filepath) {
  return filepath.split(win32.sep).join(posix.sep).replace(__root, `./`);
}

With that set up, we can now implement true hot reloading, where our code keeps running but object classes and function references get updated as we work on our files. For instance, let's say we have an index.js file like this:

// Get the URL for "this script", since that's what relative imports will be relative to:
import url from "node:url";
const __dirname = url.fileURLToPath(new URL(".", import.meta.url));

// Then import our watcher:
import { watch } from "./reload-watcher.js";

// We can set up our reload watcher to update not just the
// variable for our class, but also instances of that class:
let { Something } = await watch(__dirname, `some-module.js`, (lib) => {
  // Update our class binding:
  Something = lib.Something;

  // And then update our class instance's prototype. This only works because
  // by the time this code runs, the "instance" variable will exist.
  if (instance) {
    Object.setPrototypeOf(instance, Something.prototype);
    // This swaps the old prototype for the new code, while leaving any
    // of the instance's own properties unaffected. Something that will be
    // particularly useful for changing autopilot code *while* we're flying!
  }
});

let instance = new Something();

At this point we use that instance like we would any other class instance, but its prototype will get updated every time we save.

Is that quite a bit more work than nodemon or supervisor? Absolutely. But it's only work "up front", and in return you get true hot reloading instead of a full program restart.

Although there is one caveat: JavaScript does not officially have a module unloading mechanism, so you will be slowly filling up your memory. With an emphasis on that "slowly": you'd need to hot reload tens of thousands of times to start noticing. And of course, it's dev-only. Even if you leave it in, it won't hot reload in production (plus: what would even be touching your files in production?)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.