Global Data

Apply refactorings
Referenced by patterns
Symptom

Module-level variables, singletons, or shared mutable state that any code can read or mutate from anywhere. The variable's read and write contracts live in no single place; every consumer relies on its own implicit understanding of when the value is valid, and hides in any call that touches the global without naming it.

Goal

Access goes through a small named function that owns the read/write contract — and ideally narrows it (read-only, validated). The wrapper enforces the that the global is always valid when read; every consumer of the wrapper inherits the guarantee, and the global's lifecycle becomes inspectable from a single named surface.

Smellier version

let currentUser = null;
// ...some files later...
currentUser = newUser;

Fresher version

function setCurrentUser(user) {
currentUser = validate(user);
}
function getCurrentUser() {
return currentUser;
}
Example source: Illustrative example written for this site, not a quotation from any source.
Pressure

The of any change is the whole codebase; behavior depends on hidden write order between callers. Reasoning about state requires tracing every writer — the team's scales with the codebase. Concurrent code becomes a hazard area, and reviewers ship changes that pass single-test verification but break at runtime when global state arrives in a different order.

Tradeoff

Encapsulating access through a small wrapper adds indirection at every call site; without enforcement, code leaks past the wrapper and the safety promise becomes a . The wrapper must remain the only access path; every direct read or write that escapes resets the of the smell across the codebase.

Relief

All access sites become trivially findable; the team can add logging, validation, or a cache without touching consumers. The team's drops because the audit surface is one function instead of every file that touches the global, and changes to the read/write contract have a known, bounded blast radius the wrapper documents.

Trap

Wrapping global access without removing the global — adds ceremony while the underlying coupling stays in place. The wrapper looks like encapsulation but leaks every direct mutation back into shared state; reviewers grant the safety presumption without verifying enforcement, multiplying the team's , and the global's hazards continue with an extra layer of indirection between them and the consumer.