Hut on backward compatible legs – we compile JS for the necessary browsers


Hi, Habr! Today already course starts “Fullstack JavaScript Developer” and I decided to support the guys with this article. By the way, I myself teach on React.js course.

There is such a principle – Don’t break the web, which can be revealed as “the web always tries to maintain maximum backward compatibility.” To some extent, this principle applies to web sites and applications – your site should work not only in one specific browser, but in the whole set of different browsers and versions. But in which? There should definitely be some reasonable limits, and IE 6 and netscape navigator should not be supported, but two questions remain open: which browsers do you support and how to ensure this?

If there is backward compatibility, then something is changing. Three things are changing on the web: ECMAScript (javascript), CSS, and various Web APIs. We’ll leave CSS at the edge today, but for now, the path leads us into the jungle of modern front-end development

Let’s start with a simple

One way or another, the vast majority of modern and not so browsers support ES5, a sort of greatest common denominator. Most libraries are written or compiled in ES5 and we can do the same! You can either write directly to ES5 (I do not recommend it) or use babel or typescript

There are many tutorials on the net on how to do this, but let me mention that in babel 7, @babel/preset-es2015 is outdated (which we kindly remind official documentation) and it is recommended to use @babel/preset-env, to which the lion’s share of the article is actually devoted. But it’s easy to put a hut in a clearing, but you and I haven’t gathered here for this, let’s try to do it in a swamp (if you feel longing, then maybe it’s worth changing work)?

We do as big

The general idea is as follows – we determine which browsers we support and configure these transpilers for these browsers. Various tools will help us in this, as always, but the problem here is that they are not two, not three, but a complete basket! Therefore, I will first briefly explain what each of them does, and then we will figure out who will interact with whom and how:

Disclaimer: for integration @babel/preset-env with a standard configuration in a new project does not require an understanding of how this machinery works, but in production everything is as usual more complicated and it starts to play a role


Also exists in the editorial office caniuse-lite (it is what browserslist uses)

Probably the most famous site developers go to to find out in which browsers the necessary feature is supported. Its separate coolness lies in the fact that they have data on the use of browsers (including with a breakdown by country)


It all starts with him. browserslist (browserSlist pay attention to S) can convert a query of the form “> 0.25%, not IE11, not dead “to the list of browsers, in this case meaning all browsers that have a global share of more than 0.25% except IE11 and browsers that do not receive security updates (at the time of writing, IE 10, IE Mobile 11, BlackBerry 10, BlackBerry 7, Samsung Internet 4 and Opera Mobile 12.1)


Contains polyfills for all ECMAScript features up to the 2019th version. There have been many global changes in version 3 (

Used in babel / present-env, both 2nd and 3rd versions are supported


It contains information about which browsers what polyfills from corejs are needed. Including connects polyfill for those browsers in which there are critical bugs in the feature. For example, before Chrome 80 matchAll I didn’t throw an exception in the case of a non-global regularity, as required by the current standard, although implementation first appeared in the 73rd version


Contains information about ECMAScript features support by various browsers (I think it’s clear) and runtimes (nodejs, graalvm etc.)

Used in @babel/preset-envbut with a nuance – in the case of corejs@2 for polyfills data from compat-table, and in case corejs@3 – data from core-js-compat(they are more relevant and smart)

How does it all work

In practice, in the classic version, everything looks like this:

  • in .browserslistrc (or in package.json#browserslist) you specify browserslist query
  • in babelrc you indicate @babel/preset-env in presets and choose опцию useBuiltIns (I advise entry for usage cannot check used APIs in dependencies)
  • This browserslist query is being read. @babel/preset-env
  • @babel/preset-env gets a list of browsers from it via api browserslist and
    • uses compat-data choosing a set of plugins to be applied in your code
    • uses corejs-compat choosing which polyfill to connect

Thus, at the output you get js code that will work correctly in all specified browsers (within reasonable limits because there are different exotic browsers about the support of which there is simply no data). And our hut gets up on its feet (or on piles) and gets backward compatibility!

Is that all?

Unfortunately no, in the front end everything is again restless. There are a number of bumps about which you can easily stumble, or even get bogged down if you get off the narrow path happy path

browserslist query

Surely the project in which you are going to implement this is already a list, or at least an understanding of supported browsers. If not, then everything is simple: take defaults (this is > 0.5%, last 2 versions, Firefox ESR, not dead) and you will cover more than 90% of all browsers in general (which is actually a very good result because “everything” is right up to IE 6!). If, nevertheless, there is understanding, but you need to translate it (understanding) into query. It may not be so simple, but mainly you need to know three things:

  • comma in browserslist query means or (i.e. “or”)
  • “and” is written as and
  • negation is written as not and it is applied through and even if it is written with a comma (if someone remembers how to put negation in brackets in Boolean algebra will understand why)
  • okay four: you can conveniently test your query here (but not here S! Life is pain)

With this knowledge and careful reading documentation (and you thought you can without this?) You can tailor the list to your needs. If you have problems, let me know in the comments!

Unheard of

As stated above defaults this is > 0.5%, last 2 versions, Firefox ESR, not dead. It seems relatively clear, but if you look what does this correspond to then find there browsers about the existence of which they did not even suspect or did not know that they are still being used. Nevertheless, blindly throwing them away is not worth it, so let’s deal with those that are not in the big six and a half (Chrome, Firefox, Edge, Opera, Safari and IE). Global usage percentages are for the latest version at the time of writing.

  • QQ Browser, 0.2% –

    The Chinese browser from Tencect, used to be on Trident, now on Chromium, but there is no support information on compat-table and even on Chinese wikipedia latest version from 2017 (Chromium 53)

  • UC Browser, 2.88% –

    A very popular and another Chinese browser for Android, but there is no support data either and I don’t even know which engine it works on. If someone in the know – write

  • Baidu Browser, 0%
    And another Chinese browser, this time from Baidu (Chinese Google). As it appears not spread even in China and data to support features naturally there.
  • KaiOS Browser, 0.2% –

    KaiOS is a very interesting project – an operating system for very cheap smartphones, designed to make technology more accessible. Unfortunately, there is no support data, but I believe that you can establish contacts with developers and find out. In general, the rule of a thumb is that if there is no data, we can assume that the browser supports ES5

  • Samsung Internet, 2.73% –

    Sansung’s pretty popular Android browser, based on Chromium (11.1 Meets Chromium 75)

  • Opera Mini all, 1.17%
    A very popular browser in Africa (there is a strong preponderance of cheap mobile devices and quite expensive traffic). Doesn’t support ES6 in Extreme saving mode therefore, we can assume that it supports only ES5

What to do with them ^ of course you decide, but I highly recommend trying to support as many browsers as possible, this helps to preserve their diversity and does not trap us in IE6 (Chrome khe khe)

A look into the future

This is already a lot of information, but we still have not touched such things as

  • autoprefixer and CSS
  • Its own usage data
  • Several configurations and bundles
  • Advanced options useBuiltIns

I hope we will someday cover it in the second part, but for now, all peace, and may your hut not fall apart in any browser! And if you are interested in a course, you can learn more about it at the link.

Similar Posts

Leave a Reply