ELI5: Babel and the gang

Explaining babel in simple and digestible terms (ELI5 — Explain Like I’m 5)

I lied, I will not be ELI5-ing (explain like I’m 5) babel today. Instead, I will try and ELIN (explain like I’m new) babel. I only wish that someone would have had this conversation with me when I first heard of babel. It’s never too late I suppose :). Let’s begin.

Note (Sept 08, 2018): Article updated to reflect some of the babel v7 changes.

Past Me (PM): AFAIK, create-react-app uses babel. Seems like an interesting tool if I want to continue using all bleeding edge JS features. What’s the npm package I need to kick things off?

Current Me (CM): Not so fast mister! First, let us talk about what Babel is. As per the documentation:

Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments

Past Me (PM): Cool, so anything I write (TypeScript or ES6+) can be converted into ES5 which the browsers can understand. That’s awesome, anything else I need to know before I start off?

Current Me (CM): Yes, a couple of things. Babel, a.k.a. @babel/core, in itself is just a shell, it takes your code in and spits it out as is. What you do need are plugins which do the processing and transformations on your code.

PM: Oh, okay. How do I get the plugins ? Surely someone has created a library of these plugins , right?

CM: That’s right, there are a lot of plugins that are available on the npm registry that you can install and use based on your project. Plugins range from simple transformations such as transformation of arrow functions to more complex and sophisticated plugins such as transformation of module systems.

You need to identify the plugins that you are going to need and import them as a devDependency to your project.

PM: So importing as a devDependency is going to be enough for getting my application to work as expected?

CM: Yes. Almost. You need to further tell babel that you want it to pick certain plugins and apply them to your code. The simplest and also the recommended way of doing it is using the .babelrc file, which you can create at the root of your project, and add the plugins array in it.

{

"plugins": ["@babel/plugin-transform-arrow-functions"]

}

Alternatively, you can create and add your custom plugins and optionally pass additional parameters to it.

{

"plugins": [

["name", {

"option1": "value1",

"option2": "value2"

}]

]

}

Also, don’t forget, you need to include babel itself in your project. If you use webpack, you can use babel-loader which can be applied via a rule.

PM: That does not sound very easy though. Will I have to add each and every one of these plugins based on what ES6+ or TypeScript feature I want to use?

CM: Absolutely not! That’s why there are presets . A developer should not have to put this list of plugins together for each project. Just use the most logical preset for your project and add additional plugins or presets as necessary. Currently, only a handful of presets are supported officially. Although there are lot of plugins available, it is unlikely that you will need them in majority of cases.

PM: What are the official presets? Do they support React?

CM: They most certainly do, there are four main plugins:

@babel/preset-env: Makes your code compatible with the latest version of JavaScript (ES2017 as of now). It adds polyfills as needed. It can accept a plethora of options to support any and all of your wishes. Also, important to note that the polyfill as of v7.x.x does not support the experimental features. @babel/preset-flow: If you are using flow in your project for static type checking, you can use the preset-flow preset which comes with @babel/plugin-transform-flow-strip-types useful for stripping out the type checks that we add in our code. @babel/preset-react: Provides you all the react specific plugins, the most important one transforming JSX to JS . @babel/preset-typescript: Transforms your TS code to JS using all the plugins necessary.

Until v7.x.x Babel also provided support for experimental features of JS which are provided in what is called stages of standardization by TC39. There are a total of 5 stages, with last one being the standardization of the feature. If you want, there are presets available in npm under the name @babel/preset-stage-STAGE_NUMBER which can be included in your project as needed. Use them wisely.

Since v7.x.x arrived, the stage presets have been deprecated in the favor of explicit plugin inclusion with the plugin-proposal prefix. This was done to solve several challenges such as reduced use of stage-0 experimental features in production and many more.

PM: Cool! One last question- in my create-react-app based application, I see the babel preset used is react-app . How is that different than the @babel/preset-react ?

CM: Great question! If you look at the description of all the plugins and packages that the create-react-app projects use, you can see that they are using a lot more than the relatively simpler @babel/preset-react preset. They combine what they believe to be useful for anyone building applications using the create-react-app CLI. If you are not using the CLI then you are free to use whatever plugins and presets that you deem fit.

PM: Awesome! I guess I am ready to start using babel then. Thanks! you can go back to the future now.

CM: Sure thing :D. Do not forget to go through the documentation, faqs and understand the caveats of babel .

For an advanced understanding of the internal workings of babel, refer to the architectural handbook.