WeakMap Patterns for Leak-Free Code

Imagine a web app that autosaves user data, caches objects for speed, and attaches metadata to DOM nodes. You need fast lookups without turning your cache into a memory black hole.

Why WeakMap Matters

A regular Map holds strong references to its keys and values. Even if the key object is no longer used elsewhere, it stays alive inside the map. Over time, these orphaned entries accumulate and leak memory.

A WeakMap, on the other hand, holds weak references to its keys. If there are no other references to a key object, the GC can reclaim both the object and its associated entry in the WeakMap automatically.

Core Characteristics

Real-World Use Case: Metadata for DOM Nodes

Suppose you’re building a rich text editor. You need to store extra info for certain nodes, like whether a user has edited a paragraph, but you don’t want to attach properties directly to DOM elements or worry about cleanup when a node is removed.

const nodeMeta = new WeakMap();

function annotate(node, info) {
  nodeMeta.set(node, info);
}

function getMeta(node) {
  return nodeMeta.get(node);
}

// Usage
const para = document.createElement('p');
annotate(para, { edited: true });
// Later, if `para` is removed and no references remain,
// GC reclaims both the DOM node and its metadata entry.

No manual delete calls. No risk of stale entries.

Pattern: Caching API Responses

You fetch user profiles and cache them to avoid repeat network calls. Using a Map can leak if you never prune old entries. With WeakMap, you tie cache entries to user objects. Once the user object falls out of scope, the cache entry goes too.

const profileCache = new WeakMap();

async function getUserProfile(user) {
  if (profileCache.has(user)) {
    return profileCache.get(user);
  }
  const profile = await fetch(`/api/users/${user.id}`).then(r => r.json());
  profileCache.set(user, profile);
  return profile;
}

When user is no longer referenced, its cache entry vanishes.

Common Pitfalls and Tips

When Not to Use WeakMap

There are cases where WeakMap isn’t the right tool:

In these scenarios, choose collections that give you full control over their contents and lifecycle.

Conclusion

WeakMap is a powerful tool for managing memory in JavaScript. It lets you associate data with objects without preventing garbage collection, making it ideal for metadata, caches, and temporary storage. By understanding its strengths and limitations, you can write cleaner, more efficient code that avoids memory leaks.

What’s Next

But WeakMap isn’t the only weak structure in town. In the next post, we’ll explore WeakSet, its similarities, its quirks, and the subtle ways it lets you track objects without ever holding them back.

← Back to Blog Index   ← Back to Home