Singleton pattern in Node.js

Design patterns are incredibly useful and one of the best programming practices followed by software developers.

They provide solutions to those problems that are recurrent during software development. They are also known as GoF (gang of four) Design Patterns, and there are three types of software design patterns: Creational, behavioral, and structural.

We'll discuss one of the creational patterns called the singleton pattern.

Singleton pattern

The singleton pattern, as the name suggests, represents a single instance of a class.

To enforce this single instance rule, the class uses a private constructor. This prevents external classes from creating new instances of the class directly. The purpose of the Singleton pattern is to enforce the presence of only one instance of a class.

That single instance is responsible for coordinating actions and managing resources while providing a centralized point of control across all the components of an application.

Use cases

There are many use cases where we need to use a single instance with centralized access. There are a few use cases for using a single instance:

  • For database connections

  • For configuration management

  • For logging management

  • For sharing stateful information

  • For optimizing resource usage

  • For implementing thread pools

  • For managing the cache

Singleton pattern
Singleton pattern

Code explaination

Consider a scenario where we implement the singleton pattern using the export module. Let’s create a logger module named logger.js, that ensures there is a single instance of the logger throughout the module and a test file main.js to see how we can use the logger module.

Note: We will use the version 14 or later of Node.js.

main.js
logger.js
package.json
// Importing the public method of Logger module
import { getInstance } from './logger.js'
// Getting the singleton instance
const instance1 = getInstance()
const instance2 = getInstance()
// Checking if both instances refer to the same object or not
if (instance1 === instance2)
console.log('Both instances refer to the same object')
// Using the Logger to log messages
instance1.log('I am instance 1')
instance2.log('I am instance 2')
// Logging entries of both instances
console.log(instance1.logs)
console.log(instance2.logs)

Just a heads-up: logger.js and main.js are both in the same Code Widget. You can find them on the left side of the widget.

Explanation

  • logger.js:

    • Line 2: We declare a variable instance and initialize it to null to hold a single instance of the class.

    • Lines 5–14: The Logger class has a constructor that initializes the logs instance variable as an empty array. It also includes a log() method that adds a message to the logs array and logs it to the console.

    • Lines 17–23: The getInstance() method provides access to a single instance of the class. It checks the instance variable and, if it is null, creates a new Logger instance and assigns it to instance. It then returns this instance, ensuring that all future calls to getInstance() return the same object.

    • Line 26: This line exports the getInstance method using the export keyword.

Now let's look at the main.js file explanation below:

  • main.js:

    • Line 2: We import the getInstance function from the logger.js module using the import keyword. The getInstance function is the public method that provides access to the singleton instance of the Logger class.

    • Lines 5-6: We call the getInstance() method twice, creating two instances, instance1 and instance2 of the Logger class.

    • Lines 9-10: We check if instance1 and instance2 refer to the same object. Since the getInstance function ensures that there is only one instance, both instance1 and instance2 will refer to the same object. So, if this is true, which is expected due to the Singleton pattern, it logs the message to the console.

    • Lines 13-14: We call the log method for both instances instance1 and instance2, to log messages.

    • Lines 17-18: We print the logs array of both instances instance1 and instance2 to the console. Since both instances share the same instance of the Logger class, they also share the same logs array. The console output will show the log entries of both instances.

Conclusion

The singleton pattern is useful when we need a single access point to a resource or service. It provides a simple and centralized solution. However, since it offers global access, it should be used with care. Overuse can affect the modularity and testability of the application.

Free Resources

Copyright ©2025 Educative, Inc. All rights reserved