Skip to content
FLAVIO COPES
flaviocopes.com
2026

A short and simple guide to Babel

By

A short guide to Babel: transform modern JavaScript for specific browsers or runtimes with preset-env, Browserslist, the CLI, and webpack.

~~~

Babel is a JavaScript compiler.

It parses your source code, applies configured transformations, and prints JavaScript that your target environments can run.

You often do not need to configure Babel yourself because a framework or build tool already handles it. Add Babel when your project needs transforms that its existing toolchain does not provide.

What Babel transforms

Suppose your source contains an arrow function:

const double = (number) => number * 2

For a target that does not support arrow functions, Babel can output:

const double = function (number) {
  return number * 2
}

The actual output depends on your targets and configuration. Babel should not transform code just because a feature is new. It should transform code when one of your supported environments needs it.

Install Babel locally

Install the core compiler, command-line interface, and environment preset:

npm install --save-dev @babel/core @babel/cli @babel/preset-env

Keep Babel in the project’s development dependencies. A local install makes the expected toolchain part of the project instead of depending on a global command.

Configure @babel/preset-env

Create babel.config.json in the project root:

{
  "presets": ["@babel/preset-env"]
}

@babel/preset-env chooses syntax transforms from your target environments. It is more maintainable than listing individual syntax plugins one by one.

The preset reads Browserslist configuration. Add a .browserslistrc file:

defaults
not dead

This is only an example. Choose targets from your actual users, support policy, and application requirements.

You can inspect how a query resolves with:

npx browserslist

Read the @babel/preset-env documentation before using a copied target list. Browser versions in old tutorials become obsolete quickly.

Compile files from the command line

Compile one file:

npx babel src/index.js --out-file dist/index.js

Compile a directory:

npx babel src --out-dir dist

Add a script to package.json for repeatable builds:

{
  "scripts": {
    "build:js": "babel src --out-dir dist"
  }
}

Then run:

npm run build:js

The Babel usage guide covers the CLI and other integrations.

Syntax transforms are not API polyfills

Changing arrow-function syntax is different from adding a missing browser API.

For example, a target might understand the syntax in this code but not provide the Array.prototype.at() method:

const last = items.at(-1)

Babel’s syntax transforms do not automatically implement every missing global, static method, or prototype method.

Polyfills change the runtime environment and can affect bundle size and global behavior. Choose a polyfill strategy for the application and target browsers instead of installing an old all-in-one Babel polyfill package from a tutorial.

The @babel/polyfill package is deprecated. Current Babel documentation describes the available polyfill integrations in the @babel/preset-env guide.

Presets and plugins

A plugin performs a specific transformation.

A preset groups plugins and options for a common use case. Official presets include:

Install only the presets your source needs:

npm install --save-dev @babel/preset-react

Then add the preset:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

TypeScript’s Babel preset removes type syntax but does not type-check the program. Run the TypeScript checker separately when type safety matters.

See Babel’s preset documentation.

Use Babel with webpack

Webpack builds the module graph and bundle. Babel transforms JavaScript. Connect them with babel-loader.

Install the loader:

npm install --save-dev babel-loader

Add a rule to webpack.config.js:

module.exports = {
  module: {
    rules: [
      {
        test: /\.(?:js|mjs|cjs)$/,
        exclude: /node_modules/,
        use: 'babel-loader'
      }
    ]
  }
}

babel-loader uses the project’s Babel configuration. Excluding node_modules avoids compiling every dependency unless you know a particular package also needs transformation.

See the current babel-loader documentation and the webpack guide.

Avoid unnecessary transforms

Broad legacy targets produce more transformed code and may require more runtime support.

Keep target environments explicit, review them periodically, and test the generated build in the oldest environments you promise to support. When a framework owns the Babel setup, use its documented extension points instead of adding a second, competing configuration.

Tagged: DevTools · All topics
~~~

Related posts about devtool: