Polyfill: giving a browser a feature it does not have

A polyfill implements in JavaScript a function the engine does not provide. It fills the gaps transpilation cannot close, one method at a time.
3 min read
Believemy logo

A new method lands in the language, the documentation covers it, you use it. Then a visitor reports an error from a five-year-old device where that method does not exist.

A polyfill settles the case without giving up on modern code: it supplies the missing function, written in ordinary JavaScript.


Definition

A polyfill is a piece of code implementing a feature absent from the runtime, using only what that runtime already knows how to do. It installs itself once, at load time, and the rest of the program never has to ask the question again.

JAVASCRIPT
// Polyfill for Array.prototype.at
if (!Array.prototype.at) {
  Array.prototype.at = function (index) {
    const i = Math.trunc(index) || 0;
    const position = i < 0 ? this.length + i : i;
    if (position < 0 || position >= this.length) return undefined;
    return this[position];
  };
}

console.log([10, 20, 30].at(-1)); // 30

The if condition is the heart of the technique: if the engine already provides the method, its own version is kept. A polyfill never replaces a native implementation, it only fills a hole.


Three neighboring ideas worth separating

TermWhat it addresses
PolyfillA missing function, installed on the native object
TranspilationSyntax the engine cannot parse, rewritten before shipping
PonyfillThe same function, exported without touching the native object

The third option is the most cautious: instead of modifying Array for the whole page, it exposes a function you import explicitly. No risk of clashing with a third-party library doing the same job differently.

Good to know

Modifying a native object commits the entire page, including scripts you did not write. An approximate polyfill then produces bugs that are very hard to locate, since they surface far from the file at fault.


Do not load them for everyone

Shipping a batch of polyfills to every visitor punishes those whose browser needs none, which is to say most of them. Two approaches avoid that waste.

The first lets Babel inject only the polyfills matching the features actually used, based on the targeted browsers. The second tests for the feature at startup and loads the fallback only when needed, through import() (dynamic import).


Frequently asked questions

Question

Should I write my own polyfills?

No, except to understand the mechanism. The edge cases are numerous, often counterintuitive, and a proven library already handles them. A homemade implementation drifting slightly from the specification is worse than no polyfill at all, because the error goes silent.


Question

Can anything be filled in this way?

No. A missing method or object can be rebuilt, but unknown syntax raises an error before execution even starts: no code can catch that. Likewise, a feature requiring hardware access cannot be imitated in JavaScript.


Question

Do I still need them today?

Less and less for a general audience, since browsers update themselves. The question remains for frozen environments, such as browsers embedded in applications or older hardware. Start from your site's analytics rather than a general impression.

Related terms

Discover our javaScript glossary

Every word of JavaScript explained simply: keywords, built-in objects, methods, errors and concepts. Clear definitions and examples that actually run, to learn and to troubleshoot.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.