How Lodash uniqueId Generates Unique Identifiers

Lodash’s _.uniqueId utility guarantees distinct string identifiers within a runtime environment by combining a module-scoped lexical closure, synchronous monotonic incrementation, and automatic prefix normalization. Rather than relying on complex hashing or randomized UUID generation, Lodash uses JavaScript’s single-threaded execution context and a shared integer state to eliminate identifier collision within the module’s lifecycle.

The Lexical Module Closure

The core mechanism enforcing sequence integrity in _.uniqueId is an internal counter declared in the outer lexical scope of the utility module:

var idCounter = 0;

function uniqueId(prefix) {
  var id = ++idCounter;
  return '' + (prefix == null ? '' : prefix) + id;
}

Because idCounter is encapsulated within the module's private scope, it cannot be directly accessed, modified, or reset by external application code. Every call to _.uniqueId across an application interacts with the exact same memory reference for this variable, as long as the application resolves to a single bundled instance of the Lodash module.

Monotonic Incrementation and Single-Threaded Safety

JavaScript executes synchronously on a single-threaded event loop. When _.uniqueId runs, the pre-increment operator (++idCounter) reads the current integer value, increments it by one, and writes it back to the closure variable in a single, uninterrupted operation.

This synchronous execution guarantees:

Interleaved Sequences Across Prefixes

A common misconception is that Lodash manages separate increment counters for each unique prefix string. It does not. A single global counter is shared across all prefixes.

If _.uniqueId('user_') produces user_1, a subsequent call to _.uniqueId('order_') yields order_2, and another call to _.uniqueId('user_') yields user_3. By multiplexing all prefixes onto one monotonic sequence:

Prefix Coercion and Type Boundary Handling

To maintain boundary separation between the prefix and the numeric suffix, _.uniqueId evaluates the incoming prefix argument using a loose equality check: prefix == null ? '' : prefix.

  1. Null and Undefined Normalization: Passing null, undefined, or omitting the argument entirely substitutes an empty string (''), ensuring the return value is simply the stringified integer (e.g., '1', '2').
  2. String Casting: Non-null values are explicitly coerced into strings via string concatenation ('' + ... + id). This prevents unexpected runtime exceptions when objects, symbols, or numbers are passed as prefixes, guaranteeing a uniform string output format.

Runtime Boundaries and Limitations

The uniqueness of _.uniqueId is strictly bounded by the JavaScript runtime instance and module resolution context. It does not provide global safety across separate processes, web workers, or distributed databases. Furthermore, if a project contains multiple duplicate installations of Lodash via nested node_modules or fragmented module bundler chunks, each bundle instance initializes its own isolated idCounter closure, breaking the global non-overlapping boundary between those instances. For single-runtime, in-memory state tracking, however, the combination of module scoping and monotonic pre-incrementation provides complete safety against overlapping identifiers.