What is the Singleton pattern?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
A singleton guarantees that a class has exactly one instance and gives everyone a single point of access to it. You reach for it when one shared thing must coordinate the whole app — a database connection pool, a config store, a logger.
In JavaScript a module already is one. A module's top-level code runs once no matter how many files import it, so the simplest singleton needs no pattern at all:
// config.js
const config = { apiUrl: "/api", retries: 3 };
export default config; // every importer gets the same object
When you do want lazy creation, a closure keeps the instance private:
const getDb = (() => {
let instance;
return () => {
if (!instance) instance = new Database(); // created on first use only
return instance;
};
})();
The class version stores the instance as a static field and returns it from the constructor:
class Logger {
static #instance;
constructor() {
if (Logger.#instance) return Logger.#instance;
this.lines = [];
Logger.#instance = this;
}
}
new Logger() === new Logger(); // true
This works but is slightly dishonest — new returning an existing object surprises readers. A static Logger.getInstance() states the intent more clearly.
Use it sparingly
A singleton is global mutable state wearing a nicer name, and it brings the usual costs: any module can change it, so bugs are hard to trace; tests share state between cases unless you add a reset; and swapping it for a fake in a test is awkward. Passing the dependency in explicitly is usually easier to reason about. Keep singletons for genuinely process-wide resources, and make them read-only where you can.
