Polyfill vs. Shim
With the new ES6 specification, people talk more and more about polyfill and shim, sometimes as the term are interchangeable but, are they the same thing?
Polyfills and shims
There are many definitions and interpretation about what is Polyfill and shim. Agree that both are libraries there are some differences between them.
Shim:
- the API exists in major browser;
- has its own API;
- is more about fixing some functionality and aligning browser behavior with another browser;
- is strictly tailored for an old environment;
- is a graceful degradation.
Watch out! Saying “has its own API” doesn’t mean it exposes a broader API, more methods, but just that all the methods from the API are reimplemented. The shim intercepts all the API calls and provides its own implementation so that all the browsers have the same behavior.
Polyfill:
- is a shim for a browser API;
- is related to browsers;
- implements missing feature in an API;
- is something that you could drop in and it would silently work;
- brings future EcmaScript features back in time to old and latest browsers (regressive enhancement).
In a nutshell
Respoke has created an interesting flow chart to decide if a certain library is a shim or a polyfill. The demarcation between them is not always really sharp. Try to answer the following question and make a decision:
- Does your library fix some functionality and/or normalize a JavaScript API across the major browsers?
- Does the JavaScript API exist in some major browsers?
- Does your library implement the JavaScript API where it does not exist?
Polyfill, back to 2010
The term polyfill comes from a 2010 blog post by Remy Sharp where Remy Sharp was looking for a new term or word:
I wanted a word that meant “replicate an API using JavaScript (or Flash or whatever) if the browser doesn’t have it natively. … I wanted something you could drop in and it would silently work.
The term shim doesn’t work for him because:
I knew what I was after wasn’t progressive enhancement because the baseline that I was working to required JavaScript and the latest technology. So that existing term didn’t work for me.
So Remy gives the following definitions:
A polyfill, or polyfiller, is a piece of code (or plugin) that provides the technology that you, the developer, expect the browser to provide natively. Flattening the API landscape if you will.
Poly meaning it could be solved using any number of techniques - it wasn’t limited to just being done using JavaScript, and fill would fill the hole in the browser where the technology needed to be. It also didn’t imply “old browser” (because we need to polyfill new browser too).
Shim, to me, meant a piece of code that you could add that would fix some functionality, but it would most often have its own API.
Other definitions
I like classify polyfilling as a form of Regressive Enhancement
A shim that mimics a future API providing fallback functionality to older browsers.
A polyfill is code that detects if a certain “expected” API is missing and manually implements it. E.g.
if (!Function.prototype.bind) { Function.prototype.bind = ...; }
A shim is code that intercepts existing API calls and implements different behavior.
The idea here is to normalize certain APIs across different environments. So, if two browsers implement the same API differently, you could intercept the API calls in one of those browsers and make its behavior align with the other browser. Or, if a browser has a bug in one of its APIs, you could again intercept calls to that API, and then circumvent the bug.
A shim is a library that brings a new API to an older environment, using only the means of that environment.
A polyfill is a shim for a browser API. It typically checks if a browser supports an API. If it doesn’t, the polyfill installs its own implementation. That allows you to use the API in either case.
Polyfills and shims libraries
Paul Irish provides a list of HTML5 cross browser polyfills and shims.