promise-polyfill
A lightweight, spec-compliant ES6 Promise polyfill for browsers and Node.js environments that lack native Promise support.
Repository Health
Technical Analysis
promise-polyfill provides a drop-in implementation of the ES6 Promise API for older browsers (IE8+) and runtimes that predate native Promise support. It closely follows the Promises/A+ specification and is verified against the official promises-aplus-tests compliance suite, so it behaves identically to the native Promise object it stands in for.
The library ships two entry points: a global-installing polyfill that patches window.Promise (or adds missing static methods like finally, allSettled, and any to an existing native Promise), and a ponyfill export for library authors who don’t want to touch global state. At well under 1kb gzipped, it’s small enough to include unconditionally in a build targeting legacy browsers.
What You Get
- A full Promise implementation: constructor, then/catch/finally, and the static helpers all/race/resolve/reject/any/allSettled
- A global-installing entry point (
promise-polyfill/src/polyfill) that setswindow.Promise/global.Promiseonly when native support is absent - A ponyfill entry point (default export of the package) for code that shouldn’t mutate global state
- Prebuilt UMD bundles (
dist/polyfill.js,dist/polyfill.min.js) usable directly via a<script>tag or CDN, alongside CJS/ESM builds for bundlers - Configurable internals — override the async scheduler via
Promise._immediateFnor silence/replace unhandled-rejection warnings viaPromise._unhandledRejectionFn
Common Use Cases
- Shimming Promise support into a website that must run on legacy browsers like IE8-IE11
- Adding missing Promise statics (
finally,allSettled,any) to an otherwise-native Promise in older Node.js or partially-supporting engines - Using Promises inside a shared library without polluting the global namespace, via the ponyfill import
- Loading a zero-dependency Promise shim straight from a CDN for a static HTML page with no build step
Under The Hood
Architecture src/index.js defines the core Promise constructor plus then/catch/finally/all/race/resolve/reject, all funneled through a small internal state machine (handle/resolve/reject/finale functions operating on private _state/_value/_deferreds properties) implemented with plain closures rather than classes — no build-time codegen, just five small composable files (index.js, polyfill.js, finally.js, allSettled.js, any.js). index.js exports the constructor as a ponyfill, while polyfill.js is the side-effecting entry that assigns it to the detected global object only when a native Promise is absent, or patches finally/allSettled/any onto an existing native Promise when missing. Because every static and instance method routes through the same doResolve/handle state machine, a change to that core would require re-verifying all of them.
Tech Stack
Written in plain ES5-targeted JavaScript with JSDoc type annotations checked via tsc --checkJS and Google Closure Compiler advanced-mode checks for dead-code elimination; no runtime dependencies at all. Built with Rollup into CJS (lib/) and UMD (dist/) bundles; ESLint plus Prettier enforce style, with Husky and lint-staged gating commits. Published to both npm and Bower, and embeddable directly from the jsdelivr CDN as a UMD script.
Code Quality
Two parallel test suites cover the implementation: a Mocha unit-test file with dozens of cases covering constructor errors, then/catch/finally chaining, and edge cases across all/race/any/allSettled and unhandled-rejection warnings, plus a full run of the official promises-aplus-tests conformance suite executed through Karma in a real browser — meaning correctness is checked against the canonical A+ specification tests, not just author-written cases. Error handling is deliberate throughout doResolve (try/catch around user resolver functions guarded by a done flag against double-settlement), and naming is terse but consistent with the classic open-source promise implementation this project descends from.
API Design
Its main differentiator versus reaching for another polyfill is the dual entry-point design: import the polyfill path for a zero-config global shim ideal for app bundlers targeting legacy browsers, or import the default export as a ponyfill that never touches the global object — recommended for library authors. The public surface intentionally mirrors the native Promise API one-to-one, so swapping between native and polyfilled Promise is a single import-line change, and two documented escape hatches (Promise._immediateFn, Promise._unhandledRejectionFn) let consumers override scheduling or rejection-warning behavior without forking the library.
Used by 3 apps in this directory
Flagsmith
Developer Tools · Devops · Ab Testing Experimentation
Open-source feature flagging, remote config, and A/B/multivariate testing platform for web, mobile, and server-side apps — self-host or use the hosted SaaS.
LimeSurvey
Forms Surveys
The world's most flexible open-source survey platform with 900+ templates, conditional logic, 80+ languages, and full GDPR compliance for any scale.
Pixelfed
Social Media
A decentralized, self-hosted photo sharing platform built on ActivityPub for the open Fediverse.