Last updated: Apr 29, 2026

Singleton

The Singleton pattern restricts a class to a single instance and provides a global access point to that instance.

Intent

Sometimes you need exactly one object to coordinate actions across the system — a configuration manager, a connection pool, a logger. The Singleton pattern guarantees that a class has only one instance and provides a well-known access point.

Examples in TypeScript

Class-Based Singleton with Object.freeze

let instance: DatabaseConnection | null = null;
class DatabaseConnection {
  private host: string;
  private port: number;

  constructor(host: string, port: number) {
    if (instance) {
      throw new Error("DatabaseConnection already initialized");
    }
    instance = this;
    this.host = host;
    this.port = port;
  }

  getConnectionString(): string {
    return `${this.host}:${this.port}`;
  }
}

const dbInstance = Object.freeze(new DatabaseConnection("localhost", 5432));

export { dbInstance };

Object Literal Singleton

const appConfig = Object.freeze({
  apiUrl: "https://api.example.com",
  timeout: 5000,
  retries: 3,

  summary(): string {
    return `${this.apiUrl} (timeout: ${this.timeout}ms)`;
  },
});

export { appConfig };

ES2015 Modules Are Singletons by Default

In ES2015+, a module is evaluated once regardless of how many files import it. The exported bindings are shared across all consumers, which means any top-level object you export already behaves as a singleton.

When to Use It

  • You need exactly one instance of a class accessible from a well-known access point.
  • The single instance should be extensible by subclassing, and clients should be able to use the extended instance without modifying their code.

Common Real-World Uses

  • Database connection pools
  • Application configuration objects
  • Logging services

Trade-Offs

AdvantageDisadvantage
Controlled access to sole instanceHard to unit-test (global state)
Reduced namespace pollutionCan hide dependencies
Lazy initializationPotential thread-safety issues
  • Factory Method — can use Singleton to ensure only one factory exists.
  • Abstract Factory — often implemented as a Singleton.
  • Builder — can be combined with Singleton to reuse a complex build process.