Why you don't need Babel - LogRocket Blog (2024)

In 2020, frontend developers are still wasting a lot of time with excessive tooling. Babel is seen by some as a necessity, but I aim to show you that it’s not.

By the end of this article, you will know:

  • How to confirm which browsers actually need supporting on a case-by-case basis
  • How to lint with Visual Studio Code to avoid the need for Babel
  • Another software alternative to get the same job done faster

What is Babel and what problem does it solve?

Babel is a compiler that converts your modern JavaScript to run in older browsers. It can also perform other jobs such as converting JSX syntax, but it is not the only tool for that.

As browsers evolve, new APIs and ECMAScript features are added. Different browsers evolve at different speeds and prioritize different features. This leaves us with a tricky problem to solve: how can we support them all and still use modern features? Some will be incompatible.

A common solution is to write using the latest features and transpile down to older-style code the browser will understand. Transpiling describes a specialized type of compilation. It has different meanings in different contexts. In our case, there are also two separate parts to transpiling.

The difference between transpiling and polyfilling

Transpiling is the process of converting newer language syntax that old browsers can’t understand into the old syntax they recognize.

Here is an example of transpiling the let statement:

// the new syntax `let` was added in ECMAScript 2015 aka ES6let x = 11;// `let` transpiles to the old syntax `var` if your transpiler target was ES5var x = 11;

Polyfilling is the process of adding the missing methods, properties, or APIs to the old browsers by supplying your own version of the missing native code.

It can be thought of as filling in the gaps. For example, here is a polyfill for isNaN:

// check if the method `isNaN` exists on the standard built-in `Number` objectif (!Number.isNaN) { // if not we add our own version of the native method newer browsers provide Number.isNaN = function isNaN(x) { return x !== x; };}

The best place to get polyfils is via core-js.

Transpiling and polyfilling are sometimes impossible and can add a lot of code bloat, it’s best to avoid them altogether if possible. That is why the first alternative we’re going to discuss is the best one.

Alternative No. 1: Don’t support ancient browsers

If users would just upgrade their browsers, we could avoid the hassle of transpiling and they could enjoy the enhanced features and performance of the new browser. Unfortunately, things aren’t that simple.

The main culprit is large corporations having to support legacy software. The classic example is Internet Explorer, which has been a blight on web development from the beginning.

That said, things have improved a lot in recent years. Now, most browsers are evergreen, meaning they’re constantly updated. Microsoft now promotes its evergreen Edge browser, which, conveniently, uses the same V8 engine as Chrome, meaning one fewer engine to support.

To determine whether you have to support a particular browser, ask yourself the following questions.

Over 200k developers use LogRocket to create better digital experiencesLearn more →

1. Which browsers are your customers currently using?

If you already have a website or app that serves the same customer base, you can get this information from the analytics software. Below are some recent statistics from a UK-based sound engineering website I’m managing. If it were a JavaScript application with the same customers demographic, I would assume they would be using the same browsers.

Why you don't need Babel - LogRocket Blog (3)

If you don’t have analytic software installed, you won’t know which browsers you need to support. You’ll have to make an educated guess. If you have corporate customers, it’s far more likely you’ll need to support IE11 than if you’re marketing to web-literate technology fans.

When you support a browser, you make a commitment. Do you really want to have additional tests on every release, additional build tooling to configure, and extra dependencies to babysit?

There must be a clear financial reason to go to through all this bother. Will losing those customers who can’t access your site or app cost more than it would to support the browser?

2. Which modern browser features do you want to use?

Using modern language features and browser APIs makes writing code easier, faster, and more fun. It also makes your code more maintainable.

If you’re happy writing ES5 and using XMLHttpRequest(), you definitely don’t need Babel, but you might need some kind of therapy.

More great articles from LogRocket:

  • Don't miss a moment with The Replay, a curated newsletter from LogRocket
  • Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
  • Use React's useEffect to optimize your application's performance
  • Switch between multiple versions of Node
  • Discover how to animate your React app with AnimXYZ
  • Explore Tauri, a new framework for building binaries
  • Compare NestJS vs. Express.js

3. Which modern browser features do your customers’ browsers support?

This data is available on via Can I use, but it’s a waste of time to manually look it up. Now that you know the names of the browsers you want to support, looking up compatible features can be automated with the awesome Browserlist application (more on this in the next section).

Alternative No. 2: Use eslint-plugin-compat

You can avoid the entire transpiling process altogether and instead allow your code editor to alert you if you’re using any features that are too modern for your customers’ browsers. This is the simplest option because it:

  • Eliminates any reliance on transpilers
  • Gives you back hands-on control over your production code

If there’s a modern feature you can’t live without, you can manually polyfill it. Otherwise, you can just use the older syntax when needed.

Create a test

Before we can break down the pros and cons, we need to confirm that our Babel alternatives can do the same basic job. Let’s create a small test.

Below is the modern code we want our target environment to support once transpiled.

After the transportation, there’s a console.assert for each function to verify it’s working as intended. In the case of eslint-plugin-compat we’ll instead check that the incompatible code is being flagged in the linting.

test.js

// test nullish coalescing - return right side when left side null or undefinedconst x = null ?? "default string";console.assert(x === "default string");const y = 0 ?? 42;console.assert(y === 0);// test optional chaining - return undefined on non existent property or methodconst adventurer = { name: "Alice", cat: { name: "Dinah", },};const dogName = adventurer.dog?.name;console.assert(dogName === undefined);console.assert(adventurer.someNonExistentMethod?.() === undefined);// use browser API fetch, to check lintingfetch("https://jsonplaceholder.typicode.com/todos/1") .then((response) => response.json()) .then((json) => console.log(json));

Using the eslint env property with eslint-plugin-compat

We need a workaround for linting both language features and browser APIs together.

You can use eslint to check for the language syntax. To do that, change the env property down from es2020.

To check browser API compatibility, use eslint-plugin-compat. It uses the same Browserlist config used by Babel and other tools.

Full instruction can be found in the eslint-plugin-compat repo. We’ll use the browserlist defaults preset to use the default settings. Replace this with your own selection based on your analytics.

What is browserlist?

Why you don't need Babel - LogRocket Blog (4)Browserlist automatically selects a list of browsers based on various criteria you give it.

Have a look at the list of browsers supported by the defaults setting for browserlist. defaults is a shortcut for:

  • > 0.5 percent (browser versions selected by global usage statistics)
  • Last two versions (of every “not dead” browser)
  • Firefox ESR
  • Not dead (browsers without official support or updates for 24 months)

Head to GitHub for the full list of queries available to choose your supported browsers.

Setting up eslint-plugin-compat for Visual Studio Code

Add the following packages to your project.

npm install --save-dev eslint eslint-plugin-compat

Add the following to package.json.

 "browserslist": [ "defaults" ]

Create the following .eslintrc.json file or add these settings to your current one.

{ "extends": ["plugin:compat/recommended"], "env": { "browser": true, "es2020": true }}

Make sure you have the VS Code ESLint extensioninstalled

Now any browser API that is incompatible with the browserlist config in your package.json is shown as a linting error. You can separately control which version of ECMAScript you want to support using the env property in the .eslintrc.json file.

It would be nice if the eslint-plugin-compat automatically linted the language features as well, but this is currently an open issue.

With the IE 11 setting selected —

Why you don't need Babel - LogRocket Blog (5)

— our fetch() API is flagged.

Why you don't need Babel - LogRocket Blog (6)

Change the env property to es6.

Why you don't need Babel - LogRocket Blog (7)

You’ll immediately see an error trying to use nullish coalescing, which was released as part of Es2020.

Why you don't need Babel - LogRocket Blog (8)

Alternative No. 3: Use other software to replace Babel

Before we look at alternatives, let’s quickly review how to use Babel.

Using Babel to transpile and polyfill

First, create a mini-project directory and install the dependencies we need.

mkdir babel-testcd babel-testnpm init -ymkdir src distnpm install --save-dev @babel/core @babel/cli @babel/preset-envnpm install --save @babel/polyfill

Add the following to your package.json.

"browserslist": "defaults",

Write the test.js file into src, and then issue the following command.

npx babel src --out-dir dist [emailprotected]/env

Finally, run the file to check that the tests still work.

node dist/test.js

There should be no assertion errors, but it will say fetch is not defined since Node.js has no fetch() method. Here is the resulting transpiled code. Observe all the extra cruft and bloat added.

"use strict";var _ref, _, _adventurer$dog, _adventurer$someNonEx;// test nullish coalescing - return right side when left side null or undefinedvar x = (_ref = null) !== null && _ref !== void 0 ? _ref : "default string";console.assert(x === "default string");var y = (_ = 0) !== null && _ !== void 0 ? _ : 42;console.assert(y === 0); // test optional chaining - return undefined on non existent property or methodvar adventurer = { name: "Alice", cat: { name: "Dinah", },};var dogName = (_adventurer$dog = adventurer.dog) === null || _adventurer$dog === void 0 ? void 0 : _adventurer$dog.name;console.assert(dogName === undefined);console.assert( ((_adventurer$someNonEx = adventurer.someNonExistentMethod) === null || _adventurer$someNonEx === void 0 ? void 0 : _adventurer$someNonEx.call(adventurer)) === undefined,); // use browser API fetch, to check lintingfetch("https://jsonplaceholder.typicode.com/todos/1") .then(function (response) { return response.json(); }) .then(function (json) { return console.log(json); });

The pros and cons of using Babel

Pros:

  • This most basic setup was relatively straightforward
  • Babel has a large community for support and continued updates with 36.8k GitHub stars at the time of writing

Cons:

  • Slow compile time
  • A lot of dependencies, even if they are dev-dependencies (269 packages installed)
  • 39M of disk space used, as reported by du -sh
  • 5728 files installed, as reported by find . -type f | wc -l

Using swc to transpile and polyfill

Why you don't need Babel - LogRocket Blog (9)swc is a new competitor to Babel. It is written in Rust and up to 20 times faster. This can be very important if you find yourself waiting a long time to build your project.

To set it up:

mkdir swc-testcd swc-testnpm init -ymkdir src distnpm install --save-dev @swc/cli @swc/core browserslist

Add the following to your package.json.

"browserslist": "defaults",

Write the .swcrc config file into the project root.

{ "env": { "coreJs": 3 }, "jsc": { "parser": { "syntax": "ecmascript" } }}

Write your test file into src, then issue the following command to transpile.

npx swc src -d dist

Run the resulting file to check that the tests still work.

node dist/test.js

The resulting swc-transpiled file looks like this:

var ref, ref1;var ref2;// test nullish coalescing - return right side when left side null or undefinedvar x = (ref2 = null) !== null && ref2 !== void 0 ? ref2 : "default string";console.assert(x === "default string");var ref3;var y = (ref3 = 0) !== null && ref3 !== void 0 ? ref3 : 42;console.assert(y === 0);// test optional chaining - return undefined on non existent property or methodvar adventurer = { name: "Alice", cat: { name: "Dinah", },};var dogName = (ref = adventurer.dog) === null || ref === void 0 ? void 0 : ref.name;console.assert(dogName === undefined);console.assert( ((ref1 = adventurer.someNonExistentMethod) === null || ref1 === void 0 ? void 0 : ref1.call(ref1)) === undefined,);// use browser API fetch, to check lintingfetch("https://jsonplaceholder.typicode.com/todos/1") .then(function (response) { return response.json(); }) .then(function (json) { return console.log(json); });

The pros and cons of using swc

Pros:

  • swc is much faster
  • Far fewer dependencies (43 packages installed)

Cons:

Other alternatives: Google Closure Compiler and TypeScript

I did not include Google Closure Compiler as an option because it’s notoriously complicated to use. That said, it can do a good job of transpiling and polyfilling. If you have some spare time on your hands, I recommend you check it out — especially if you value small file sizes since its built-in minification is demonstrably superior.

You can also use TypeScript to transpile and core-js to manually polyfill, but this is a clumsy solution that could easily create more problems than it solves.

Conclusion

You don’t automatically need to support old browsers. It’s important to first look at your analytics data to see which browsers your customers are actually using.

If necessary, you can use linting to ensure backward compatibility. This will save you the hassle of creating a special build step and relying on transpilation.

If you do opt for automatic translating, then SWC is much faster than Babel and contains far fewer dependencies. There is also the option to use Google Closure Compiler or TypeScript, but these will require a bit more work to configure.

Cut through the noise of traditional error reporting with LogRocket

LogRocket is a digital experience analytics solution that shields you from the hundreds of false-positive errors alerts to just a few truly important items. LogRocket tells you the most impactful bugs and UX issues actually impacting users in your applications.

Then, use session replay with deep technical telemetry to see exactly what the user saw and what caused the problem, as if you were looking over their shoulder.

LogRocket automatically aggregates client side errors, JS exceptions, frontend performance metrics, and user interactions. Then LogRocket uses machine learning to tell you which problems are affecting the most users and provides the context you need to fix it.

Focus on the bugs that matter — try LogRocket today.

Why you don't need Babel - LogRocket Blog (2024)
Top Articles
Latest Posts
Article information

Author: Pres. Lawanda Wiegand

Last Updated:

Views: 6189

Rating: 4 / 5 (71 voted)

Reviews: 94% of readers found this page helpful

Author information

Name: Pres. Lawanda Wiegand

Birthday: 1993-01-10

Address: Suite 391 6963 Ullrich Shore, Bellefort, WI 01350-7893

Phone: +6806610432415

Job: Dynamic Manufacturing Assistant

Hobby: amateur radio, Taekwondo, Wood carving, Parkour, Skateboarding, Running, Rafting

Introduction: My name is Pres. Lawanda Wiegand, I am a inquisitive, helpful, glamorous, cheerful, open, clever, innocent person who loves writing and wants to share my knowledge and understanding with you.