Design Patterns 4: The Singleton

September 03, 2018

A traffic light

The Singleton design pattern is a very common pattern in Javascript. In fact, if you’ve written any significant amount of code in JS you’ve probably used it (even if you didn’t know it!)

There are many analogies that can be used to help understand the singleton pattern, but one of my favorites is that of a shared printer. Imagine an office floor with dozens of employees sitting at desks - now imagine each of these employees has a small desktop printer. The office could function with this setup, but there are problems with this approach. Dozens of printers means dozens of maintenance schedules to follow, dozens of updates to perform, and dozens of places where problems could happen.

Our imaginary office would be much more efficient if all the employees could share a single, more robust printer with a common job queue. The printer might be a bit more complicated to set up initially since it would need to deal with more than just one input, but it would allow us to easily scale and modify our office’s printing needs.


The shared printer in this analogy is a great example of a singleton. One, shared resource that has an interface exposed to the rest of the application.


In the Angular framework, many services are registered at the app module level and set up as singletons (the Angular Router being one example). In vanilla JS, singletons are generally set up as globally accessible namespaces.

One well-known example is the JQuery library, a foundational building block of many websites before modern javascript features became standard. The $ in code using JQuery refers to a single instance of the JQuery object, and namespaces all of the JQuery methods.

Here’s an example of a singleton implementation using ES6. Notice the reference in the constructor to the singletonInstance variable - this limits the instantiation to one occurrence of the Singleton object.

let singletonInstance = null;

class Singleton {
  constructor() {
    // Check if the instance exists or is null
    if (!singletonInstance) {
      // If null, set singletonInstance to this Class 
      singletonInstance = this;
      console.log('singleton instance created')
    } else {
      console.log('you are referencing the existing singleton class');
    }
    // Returns the initiated Class
    return singletonInstance;
  }

  speak(){
    console.log('hello')
    }
}

// Create a new instance of singleton Class
let singleton1 = new Singleton();
let singleton2 = new Singleton();

singleton1.speak();
// 'hello'
singleton2.speak();
// 'hello'
console.log(singleton1 === singleton2)
// true

The singleton pattern has its limitations - it can lead to objects that are used in too many places, making testing changes very difficult. Used correctly, however, it is an important and useful design pattern in javascript.

For more on the singleton pattern, including some tips on using a singleton in a module, check out [this article].(https://www.sitepoint.com/javascript-design-patterns-singleton/)

Another good article about some of the potential drawbacks to the singleton pattern can be found [here].(https://www.sitepoint.com/whats-so-bad-about-the-singleton/)

I hope this helped you understand the basics of the singleton pattern - happy coding!


John D Potts

John D Potts

Web developer and speaker in Charlotte, NC.