In JavaScript applications, object creation strategy directly affects maintainability, scalability, and testability. One common design decision is whether to use a singleton or a non-singleton object.
This article breaks down the differences, use cases, and best practices with practical JavaScript examples.
What Is a Singleton?
- A singleton is an object designed so that only one instance exists across the entire application. Any request for that object returns the same instance.
- Singletons are commonly used for shared resources where multiple instances would be wasteful or harmful.
Characteristics:
- Single global instance
- Shared state across the app
- Controlled creation logic
- Harder to test if tightly coupled
JavaScript Singleton Example:
- In JavaScript, ES modules are singletons by default. Ex:- // config.js const config = { apiUrl: 'https://api.example.com', timeout: 5000 };
export default config;
- Every import of config receives the same object instance.
Class-Based Singleton Example:
class Logger {
constructor() {
if (Logger.instance) {
return Logger.instance;
}
this.logs = [];
Logger.instance = this;
}
log(msg) {
this.logs.push(msg);
}
}
export default Logger;
- Calling new Logger() multiple times always returns the same instance.
What Is a Non-Singleton?
- A non-singleton is a regular object or class that allows multiple independent instances, each with its own state.
- This is the default behavior in most object-oriented designs.
Characteristics:
- Multiple instances allowed
- Instance-specific state
- Easy to test and mock
- Simple construction logic
Non-Singleton Example:
class User {
constructor(name) {
this.name = name;
}
}
const u1 = new User('A');
const u2 = new User('B');
- Each new User() call creates a separate object.
Quick Comparison:
| Attribute | Singleton | Non-Singleton |
|---|---|---|
| Instance count | One global instance | Multiple instances |
| Use case | Shared resources | Domain entities |
| State | Shared | Isolated |
| Testability | Harder | Easier |
| Complexity | Higher | Lower |
When to Use Each:
Use Singleton When:
- Managing shared resources (DB, logger)
- Centralizing app configuration
- Implementing caches or feature flags
Use Non-Singleton When:
- Creating domain entities (users, orders)
- Building UI components
- Handling request-specific or temporary data
Pitfalls & Best Practices:
- ❌ Avoid overusing singletons—they introduce hidden global state
- ❌ Don’t use singletons for domain models
- ✅ Prefer dependency injection for better testability
- ✅ In Node.js, rely on module exports for safe singletons
Final Thoughts.
- Singletons are powerful—but dangerous when misused.
- Non-singletons are boring—but safe and scalable.
- The key is intentional design:
- Shared resource → Singleton
- Multiple entities → Non-Singleton
Top comments (0)