The JavaScript environment is quite dynamic. New features, attributes, or techniques are introduced on a regular basis. The issue is that not every JavaScript environment (which is a web browser) keeps up with implementation and updates. As front-end developers, we frequently deal with feature compatibility and must test our solutions across several browsers in various (sometimes outdated) versions. When it comes to implementing the ECMAScript standards, each of the main browsers has its own approach.


Why support older browsers?

You must examine who your web application will be designed for. If you create a new project in React or Angular, you won't have to worry about Internet Explorer 11 or previous Firefox versions. The issue mostly affects long-term projects with a large codebase that has been built and maintained for many years by numerous developers. The number of users who continue to use older browsers is significant. Because of the large number of users, there is still a requirement to keep the program running on older systems, such as Internet Explorer 11.


Understanding Transpilers


Luckily, we have some tools that help us to just don't think about this problem. The first, and easier option is to use the transpilers. JavaScript transpilers are tools that just take code and transform it into a version that is more "understandable" than other browser versions. The most popular among the JS family is Babel. If you use Webpack or Parcel, chances are good that there is Babel under the hood. Babel takes your modern JS code and transforms it into the older syntax.


Let's consider this simple example. We want to create a class User. Class syntax (which is just a syntactic sugar) was introduced in ES6. It is not supported in some older popular browser versions and Internet Explorer 11. The same goes for another popular property, arrow functions which are not supported by IE11.


class User {

  constructor(name) {

    this.name = name; 

  }

}


If we use these features in our code and run it in a browser that does not support it, we will get an error in a console.


Syntax Error


The code below is the same as above but transpiled by Babel.


function _classCallCheck(instance, Constructor) {

  if (!(instance instanceof Constructor)) {

    throw new TypeError("Cannot call a class as a function");

  }

}


var User = function User(name) {

  _classCallCheck(this, User);


  this.name = name;

};



Understanding Polyfills

However, some new language features may not be already included in your transpiler versions. Using polyfill is helpful in filling some gaps between browser compatibility in a controlled way. Basically, in web development, a polyfill is just a code that implements functionality that is not available on a web browser. To provide these features we can write our own versions of these functions which can be used across our web application.

A good option is to keep all of the polyfills in one place and use them only if you need to. Let's take an Array flat() method. It's not supported in IE11.


if (!Array.prototype.flat) {
    Array.prototype.flat = function(depth) {
    var flattend = [];
    (function flat(array, depth) {
      for (let el of array) {
        if (Array.isArray(el) && depth > 0) {
          flat(el, depth - 1);
        } else {
          flattend.push(el);
        }
      }
    })(this, Math.floor(depth) || 1);
    return flattend;
  };
}


So if there is no appropriate method available on the Array prototype, we create our own. Of course, we have to use methods and syntax which is supported by the standard or browser that we want to target.

Some functions are more complicated and few lines of code are just not enough to make it work. Promise is not supported by IE11. To use it, there's need to load a package:


<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.js"></script>
<script src="https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.js"></script> 

This solution is good in smaller projects when you need to polyfill only a few methods. You can add new functions if your application grows.


There are polyfill libraries which are constantly updated and maintained by the community and these are the great solution for a larger projects:



Conclusion


Using transpilers is the most popular way to keep your code running across almost every browser version. You can mimic the functionality with polyfills and can be used in your project. 

If you have any doubt, please let us know in comments.