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

Iain Collins
3 min readSep 14, 2015

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:

var HelloWorld = (function () {  this.greeting = “Hello, World”;  return this;})();module.exports = HelloWorld;

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.

var helloWorldA = require(‘./hello-world’);
var helloWorldB = require(‘./hello-world’);
// Change the value of 'greeting' from "Hello, World" to "Hi"
helloWorldA.greeting = "Hi";
// Outputs "Hi" twice
console.log(helloWorldA.greeting);
console.log(helloWorldB.greeting);

Avoid singleton behaviour by…

--

--