weakmap-polyfill

A lightweight, spec-compliant ES6 WeakMap polyfill for browsers and JS engines without native support.

Library
npm
v2.0.4
32stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
22/100Needs Attention
Development Activity0
Maintenance0
Community16
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
59/100Fair
Architecture65
Code Quality60
Innovation55
Learning Curve55

weakmap-polyfill implements the ECMAScript 2015 (ES6) WeakMap object for environments that don’t provide it natively, such as older browsers like IE7+ and Firefox 3+. It follows the ECMA-262 23.3 WeakMap Objects specification closely, tagging each key object with a hidden, non-enumerable property that stores the associated value, so garbage collection semantics stay close to a native implementation without requiring any external dependencies.

The library is a single self-contained file with zero runtime dependencies, distributed as both a plain script (weakmap-polyfill.js/.min.js) for direct <script> inclusion and as an npm module for import/require usage. It self-detects whether WeakMap already exists in the global scope and simply does nothing if so, making it safe to include unconditionally in a build without any feature-detection wrapper on the consumer’s side.

What You Get

  • A drop-in WeakMap global that mirrors the ECMA-262 23.3 WeakMap Objects specification (constructor, get, set, has, delete)
  • Automatic no-op behavior when native WeakMap is already present, so it’s safe to include unconditionally
  • Zero runtime dependencies and a tiny footprint (~2KB minified)
  • Both a UMD-style global build (weakmap-polyfill.min.js for <script> tags) and an npm-installable module for import/require
  • Documented compatibility down to Chrome 15, Firefox 3, IE7, Safari 4, and Opera 11.5

Common Use Cases

  • Shipping code that uses WeakMap-based private-state patterns to a browser matrix that still includes very old browsers
  • Polyfilling WeakMap in embedded/webview or kiosk environments running outdated JS engines
  • Backfilling WeakMap for libraries or frameworks that assume ES6 collection types are always available
  • Standalone <script> inclusion in legacy pages that can’t run a full ES5-shim/core-js bundle

Under The Hood

Architecture The entire polyfill lives in one IIFE in weakmap-polyfill.js that self-installs onto whichever global object is detected (globalThis, self, window, or global, in that priority order) and exits immediately if a native WeakMap is already present. Internally, each WeakMap instance is identified by a randomly generated _id string (via genId/rand), and set(key, value) stores the [key, value] pair as a non-enumerable property on the key object itself, keyed by that _id — so lookups (get/has/delete) are simple property reads on the key rather than a separate internal table. This trades a strict WeakMap implementation for one that piggybacks on the JS engine’s own object property storage and GC behavior, which is why the README documents known deviations (no iterable constructor argument, no support for frozen/sealed objects as keys).

Tech Stack The library has zero runtime dependencies (package.json dependencies: {}) and targets plain ES5-compatible JavaScript so it can run in the same old browsers it’s polyfilling for. Dev tooling is karma + karma-mocha + power-assert for cross-browser test execution (Chrome, Firefox, IE, Safari launchers configured in karma.conf.js), mocha for Node-side tests, eslint (eslint:recommended base config, ES6 parser) for linting, and uglify-js to produce the minified build via the minify npm script.

Code Quality Tests are split across tests/test.js (the shared assertion suite), tests/test-node.js (runs it in Node with es5-shim loaded to simulate legacy environments), tests/test-node-polyfill.js (deletes the global WeakMap to force the polyfill path), and tests/test-legacy.js, plus a tests/browser-tests/ directory with static HTML pages for manual/CI browser verification. CI was wired through Travis CI (.travis.yml, testing against Node 10-16 plus real browsers via karma), though Travis CI is largely inactive industry-wide today and the project’s own activity has slowed accordingly. There is no TypeScript or type-checking, consistent with a small ES5-targeted polyfill; error handling is minimal but appropriate (throws TypeError for spec-mandated cases like missing new or an unsupported iterable argument).

API Design The entire public surface is the global WeakMap constructor itself — there is nothing to import and call by name beyond import 'weakmap-polyfill' (or a <script> tag) before using new WeakMap() as if it were native. That zero-configuration, side-effect-only integration model is the library’s main ergonomic strength: consuming code needs no polyfill-specific API at all, just the side-effecting import placed before first use.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search