As developers, we love to use the latest and greatest technology available. At the same time, we need to make sure everything will work smoothly for our users. In the frontend world, there’s a huge difference between the code we write and what eventually gets to our users. Let’s have a look at the tools that enable us to write modern code.
We will need two main ingredients: transpilers and polyfills.
Transpilers take source code written in some programming language, transform it, and return the output in the same language. The result is still human-readable, as opposed to compilers, which typically return machine-readable byte code.
Polyfills implement missing pieces of functionality in the browser itself. When there’s a new feature or standard, the browsers need time to implement it. Even when they do, we cannot rely on our users having installed the latest version of the browser.
Now let’s dive into these tools in more detail. Here’s an example of a commonly used setup:
When you decide what browsers you want to support in your app, you can formalize it using a browserslist query. Choose a specific version, date of release, usage share, etc., and browserslist then converts the query into a format other tools can understand.
Typically, you will have a different configuration for local development and production build. Developers tend to have the latest browser versions, so there’s no need for additional overhead.
You can play with browserslist at https://browserslist.dev.
A collection of polyfills and likely the most widely used one. It’s highly modular, meaning you can pick only the pieces you need for your code to work, manually or automatically.
The complete list of available features can be found at https://github.com/zloirock/core-js#features.
Now you might be wondering how all this connects and how we can make use of it. The connecting link here is babel. A transpiler that transforms the source code according to our settings, optimizes it and injects the polyfills needed.
Babel can do more than that and is highly configurable through presets and plugins. The scenario described above is achieved through the most popular preset called @babel/preset-env.
Initially, babel was called 6to5 because all it did was transform the new ES6 syntax and functions to ES5, which browsers at the time could understand.
It is fair to point out that babel is not as fast as its modern competitors, such as SWC, but going down this rabbit hole of tooling would make for a separate series of articles.
Where’s the catch?
We need to be aware of some trade-offs caused by these tools, such as:
- degraded performance
- increased bundle size
- longer build time
If we go too far on the safe side (e.g., support IE11), we will make a worse user experience for everyone else. It is therefore important to strike a balance. For that, browserslist has some reasonable defaults based on the global market share of each browser. And for individual features, there are two great sites that also act as compatibility databases. They map each feature to a specific version of the browser in which the feature has been implemented: Can I use and MDN.
Let’s put all this into practice. There’s a great online playground on https://babeljs.io/repl where you can try all the different babel configurations, even with an integrated browserslist field.
How do I use this?
It may sound surprising, but I wouldn’t recommend setting this up from scratch. There’s much more to the whole setup than what we’ve covered here. But hey, good news! In most frameworks and meta-frameworks, such as
Next.js, all of this is already set up for you. You only need to decide what browsers you want to support, configure
browserslist and add
import 'core-js/stable' to your main entry file.
In this post, we’ve explored how browserslist, core-js, and babel team up to make web development a success. Just like a chef blending flavors, these tools work together to ensure your modern code runs smoothly on all browsers. The secret ingredient is finding just the right balance of compatibility and performance.