What is the difference between polyfill and transpiler?

Solution 1:

Both approaches serve the same purpose: You can write code, that uses some features, which are not yet implemented in your target environment. They do this, however, by using different techniques.

A polyfill will try to emulate certain APIs, so can use them as if they were already implemented.

A transpiler on the other hand will transform your code and replace the respective code section by other code, which can already be executed.

Typically you use a polyfill, if your target browser did not yet implement the latest bleeding edge feature (read browser APIs) you want to use. A transpiler on the other hand will let you use language features, the target environment does not support yet, e.g. some ES6 features like fat arrow functions.

Solution 2:

Polyfill

The word polyfill is an invented term (by Remy Sharp) used to refer to taking the definition of a newer feature and producing a piece of code that’s equivalent to the behavior, but is able to run in older JS environments.

For example:

ES1 defines a method called isNaN(value) to determines whether a value is an illegal number (Not-a-Number).

ECMAScript 1 isNaN method

ES6 defines a method called Number.isNaN(value) too determines whether a value is NaN (Not-a-Number).

ECMAScript 6 isNaN method

If you notice, Number.isNaN() is not supported in every browser, so for this purpose you can polyfill the method. Not all new features are fully polyfillable. Sometimes most of the behavior can be polyfilled, but there are still small deviations. You should be really, really careful in implementing a polyfill yourself, to make sure you are adhering to the specification as strictly as possible. Or better yet, use an already vetted set of polyfills that you can trust, such as those provided by ES5-Shim and ES6-Shim.

// These method is a sample of making polyfill 
if (!Number.isNaN) {
    Number.isNaN = function isNaN(x) {
        return x !== x;
    };
}

Transpile

There’s no way to polyfill new syntax that has been added to the language. The new syntax would throw an error in the old JS engine as unrecognized/invalid. So the better option is to use a tool that converts your newer code into older code equivalents. This process is commonly called “transpiling” a term for transforming + compiling.

There are several important reasons you should care about transpiling:

  1. The new syntax added to the language is designed to make your code more readable and maintainable. The older equivalents are often much more convoluted. You should prefer writing newer and cleaner syntax, not only for yourself but for all other members of the development team.
  2. If you transpile only for older browsers, but serve the new syntax to the newest browsers, you get to take advantage of browser performance optimizations with the new syntax. This also lets browser makers have more real-world code to test their implementations and optimizations on.
  3. Using the new syntax earlier allows it to be tested more robustly in the real world, which provides earlier feedback to the Javascript committee (TC39). If issues are found early enough, they can be changed/fixed before those language design mistakes become permanent.

There are quite a few great transpilers for you to choose from. Here are some good options at the time of this writing:

  1. Babel (formerly 6to5): Transpiles ES6 and above into ES5
  2. Traceur: Transpiles ES6, ES7, and beyond into ES5

Solution 3:

Both pollyfill and transpilation enable you to use new features in old environments (old vs new browsers for example), the main difference is that a pollyfill do that by implementing the feature in the old environment itself. So if we go by Es6 Es5 terminology, polyfill enable you to use a new feature by implementing it in Es5, however some new features can never be implemented in Es5, think for example about the arrow syntax introduced by Es6 and this is where transpilation is needed.

So an example where transpilation is needed is arrow syntax (() => {}) because u can never implement that in es5, and an example where a pollyfil can be used is for example if u wanted to implement the Array.prototype.includes method, you can easily implement it like this

// taken from mdn
if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    'use strict';

    if (search instanceof RegExp) {
      throw TypeError('first argument must not be a RegExp');
    } 
    if (start === undefined) { start = 0; }
    return this.indexOf(search, start) !== -1;
  };
}

Now here are some major differences:

  • A pollyfill will use the native feature if it exists, however transpilation will not. that leads to the conclusion that Polyfills should be preferred over transpilation, because of security and performance reasons.
  • Transpilation is about language syntax, while pollyfill is about language syntax and native browser APIs (or other environment APIs).
  • Transpilation is at compile time, while pollyfill is at runtime, and this is what differentiates one from the other.

Solution 4:

Polyfilling is like copying a feature so that one can use it. In polyfilling, one write code to get a similar functionality as provided in other JS version.

Transpilling convert code which has new syntax using transpiler so that it can be used in browsers having older Js versions.