And so, let us set about making our modern code run in non-modern browsers. We can achieve this in one of two ways…

(If you’re Captain Advanced, you may want to skip the primer and head on down to Polyfills and performance.)

Transpiling vs polyfilling

For quite a while I wasn’t clear on the difference between transpiling and polyfilling, as strange as that seems to me now. So on the off chance that you’ve never had the talk about transpiling and polyfilling, let me attempt to explain.

Transpiling

A transpiler takes the syntax that older browsers won’t understand (e.g. classes, ‘const’, arrow functions), and turns them into syntax they will understand (functions, ‘var’, functions).

So you can write devilishly handsome code like this:

Then run it through a transpiler such as Babel, and it will be turned into this glorious monstrosity:

Have a play in Babel’s online transpiler

The syntax, you will note, has been changed into something that all browsers will understand.

You might be thinking “hey neato, this code will work in IE9 now because it’s been transpiled”!

I applaud your attitude, but you are wrong.

For you see, I used the new includes array instance method. And if you look carefully at the transpiled code, it’s still there. You would be forgiven for thinking that arr.includes(item) would be transpiled into arr.indexOf(item) > -1 or something.

Forgiven, but still wrong.

So our syntax has been sorted out, but we still have code that uses ES2016 features, and these will not work in IE9 — because that year didn’t exist when IE9 came out.

So, transpiling gets us some of the way there, but we need a way to teach these older browsers what ‘includes’ means.

[psst, polyfills heading, that’s your cue]

Polyfills

A polyfill is code that defines a new object or method in browsers that don’t support that object or method. You can have polyfills for many different features. Maybe one for Array.prototype.includes , and two more for Map and Promise .

If you want to check out what a polyfill actually looks like as readable code, MDN often has examples of polyfills for particular features, and does not let us down when it comes to array.includes().

Transpilers and polyfills can do everything, that’s wonderful!

I applaud your efforts to use the word ‘awesome’ less, but no, you’re wrong.

Transpilers and polyfills can’t do everything.

It isn’t always clear what can be polyfilled or transpiled, especially if you don’t know much about how the feature in question works. Here’s a spattering of features to give you an idea of how each can be converted to be used in older browsers.

A good general rule is this:

If it’s new syntax, you can probably transpile it

If it’s a new object or method, you can probably polyfill it

If it’s something clever that the browser does outside of your code, you’re probably SOL

But I’m afraid that my peach table belies some gray areas.

Can window.crypto be polyfilled? Hmmm, my legal team doesn’t want me to answer that.

Can Element.scrollIntoView() be polyfilled? Well, pro tip: if a polyfill requires jQuery to work, I suggest you run — not walk — in the opposite direction. And not that pointless run people do when crossing the road. I mean chased-by-octo-dog run.

OK are you back from all of those hyperlinks? Good.

Where can I find polyfills?

There is a central registry of all polyfills that have been vetted by the W3C called polyfill-central.

[chuckles sensibly]

Of course there is no central anything, this is web development; there is the usual mess of sources and varying levels of quality.

Babel to the rescue again. A lot of what you will ever need you will find in babel-polyfill or more specifically: core-js (which is what babel-polyfill uses). If the feature you want to polyfill is in there, use it.

(Quite a few people seem to have their favourite Promise polyfills, which I don’t understand. But I also don’t understand parties or the recent creative decisions of Lilly Allen, so whatever. My suggestion: use the promise polyfill in core-js.)

If the polyfill you want is not in core-js, try:

caniuse.com (the resources tab sometimes has polyfills)

npm

check if MDN has something you can copy/paste

if still no luck, then just search on AltaVista (or whatever hipster search engine you use)

Here seems a good place to throw in a usual caution: people that write polyfills do not require a licence.