Guide to Babel Plugins, Presets, and JS Pipelines

Babel is a toolchain primarily used to convert modern ECMAScript code into backwards-compatible versions of JavaScript for older browsers or runtimes. This article explains the core concepts of Babel plugins and presets, details how they operate within the compilation lifecycle, and illustrates how to configure an efficient JavaScript transformation pipeline.

The Babel Transformation Pipeline

Babel processes source code through a three-stage pipeline:

  1. Parsing: The input JavaScript is converted into an Abstract Syntax Tree (AST).
  2. Transformation: The AST is manipulated, modified, or rewritten based on defined rules.
  3. Generation: The transformed AST is printed back into standard JavaScript strings.

By default, Babel does not perform any transformations on its own. Without additional instructions, it simply parses the code and outputs the identical structure. Plugins and presets provide the logic required during the transformation stage.

What Are Babel Plugins?

Babel plugins are small, targeted JavaScript programs that define specific AST transformations. Each plugin is responsible for handling a single syntax feature or transformation rule.

Plugins typically fall into two categories:

What Are Babel Presets?

A Babel preset is a shareable bundle of plugins designed to support a specific environment, framework, or language superset. Managing individual plugins for every modern JavaScript feature is tedious and error-prone; presets simplify this by grouping relevant plugins together.

Common official presets include:

Configuring Transformation Order and Options

Babel configuration is typically defined in a babel.config.json or .babelrc.json file. The execution pipeline follows strict ordering rules:

Here is an example configuration demonstrating preset execution and option passing:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "> 0.25%, not dead",
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": [
    "@babel/plugin-proposal-class-properties"
  ]
}

In this pipeline:

  1. @babel/plugin-proposal-class-properties runs first to transform custom class fields.
  2. @babel/preset-react runs second, converting JSX into React.createElement or new JSX runtime calls.
  3. @babel/preset-env runs last, taking the resulting output and transforming remaining modern ECMAScript features based on the specified browser targets.

By combining discrete plugins for specific features and comprehensive presets for broader environment targets, you can build a predictable and modular JavaScript compilation pipeline.