How (not) to create a singleton in Node.js

This morning a colleague asked me a question about exporting a module in Node.js and how to export a singleton and I had trouble coming up with an answer that covered the different ways you can create a module in Node.js, and we know what that means.

If you can’t explain it simply,
you don’t understand it well enough.

Albert Einstein

From looking at Stack Overflow which referenced the Node.js documentation it rapidly became apparent the real question was actually how to avoid creating something that behaves like a singleton.

The Node.js documentation states:

This means (among other things) that every call to require(‘foo’) will get exactly the same object returned, if it would resolve to the same file.

Multiple calls to require(‘foo’) may not cause the module code to be executed multiple times. This is an important feature. With it, “partially done” objects can be returned, thus allowing transitive dependencies to be loaded even when they would cause cycles.

If you want to have a module execute code multiple times, then export a function, and call that function.

It’s important to note that this applies to require statements that resolve to same file anywhere in your application.

Typical module declaration

If you want to create something that behaves like a singleton, you might normally do something like this in your module:

This would mean that if you load the module multiple times in your application, even in different files, HelloWorld will be invoked only once; and all instances of HelloWorld will point to the same object.

Avoid singleton behaviour by returning a module as a function then executing it

If you are trying to avoid this behaviour — perhaps because you are tracking the state of something within a module — you can instead declare your module like this:

And include it by specifying the new keyword after requiring it.

Note the parenthesis matter; you wouldn’t want to do “new require(‘./hello-world-function’)” as that would just create a new require object, not a new instance of the object you are requiring.

If you did that your code would execute but it would actually be returning something that behaved like a singleton and not creating a new instance.

An alternative, easier to read syntax for doing the same thing is:

Example usage and output

In the following example helloWorldA and helloWorldB behave like singletons while helloWorldC and helloWorldD behave like unique instances of the module.

The output from the above code is:

What’s going on here is helloWorldA and helloWorldB actually just referrer to the same cached instance of the hello-world module, while helloWorldC and helloWorldD are completely seperate objects.

How not to not create a singleton

The magical singleton behaviour is actually caused by require caching objects.

As some Stack Overflow threads get into it’s possible to access the require cache and invalidate it as an alternative way to cause code in modules to be executed every time they are invoked — but messing with cache invalidation rarely ends well.

There are only two hard things in Computer Science:
cache invalidation and naming things.

Phil Karlton

Written by

Software for news and media and civic tech. Cat herder. Director at Glitch Digital.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store