Skip to content

BabelJs - Babel Presets

Babel presets are collections of Babel plugins grouped together for convenience. Instead of specifying dozens of individual plugins for common JavaScript features, you can use a preset. Presets simplify Babel configuration significantly.

We will discuss some of the most important and widely used Babel presets:

  • @babel/preset-env: The most crucial preset for modern web development.
  • @babel/preset-react: For transforming JSX and other React-specific features.
  • @babel/preset-typescript: For working with TypeScript.
  • @babel/preset-flow: For working with Flow type annotations (less common now but still supported).

To use presets, you typically define them in your Babel configuration file (e.g., babel.config.json or .babelrc.json).

First, ensure you have a Node.js project. If not, create one:

npm init -y

Install Babel’s core and CLI tools:

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

@babel/preset-env is a smart preset that allows you to use the latest JavaScript features without needing to micromanage syntax transforms. It automatically determines the Babel plugins and polyfills needed based on your targeted environments.

Installation:

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

Configuration (babel.config.json):

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

By default, without any options, @babel/preset-env transpiles all ECMAScript 2015+ syntax to ES5. However, its real power comes from its configuration options:

  • targets: Specifies the environments you want to support (e.g., specific browser versions, Node.js version). Babel will then only transpile features not supported by those targets.
  • useBuiltIns: Configures how @babel/preset-env handles polyfills (with core-js). Options include "entry", "usage", or false (default).
  • corejs: Specifies the version of core-js to use for polyfills when useBuiltIns is active.

Create main.js:

const greet = (name) => `Hello, ${name}!`;
console.log(greet('World'));

Transpile it:

npx babel main.js --out-file main_compiled.js

main_compiled.js (with default @babel/preset-env settings):

"use strict";
var greet = function greet(name) {
return "Hello, ".concat(name, "!");
};
console.log(greet('World'));

If you configure babel.config.json to target modern environments that support arrow functions and template literals:

{
"presets": [
["@babel/preset-env", {
"targets": {
"chrome": "80",
"firefox": "70"
}
}]
]
}

Then, transpiling the same main.js might result in less transformation, as these browsers support those features:

main_compiled.js (with modern targets):

"use strict";
const greet = name => `Hello, ${name}!`;
console.log(greet('World'));

This demonstrates how @babel/preset-env adapts its output based on your specified targets, leading to more efficient and modern code where possible.

This preset is essential for projects using React. It includes plugins for transforming JSX into React.createElement calls, and other React-specific syntax like Display Name transformation.

Installation:

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

Configuration (babel.config.json, often used with @babel/preset-env):

{
"presets": [
"@babel/preset-env",
["@babel/preset-react", {
"runtime": "automatic" // Recommended for modern React (17+)
}]
]
}

The "runtime": "automatic" option (default in Babel 8, available since React 17) automatically imports the necessary JSX runtime functions, so you don’t need to import React from 'react' in every file just for JSX.

Create app.jsx:

const element = <h1>Hello, React World!</h1>;

Transpile it:

npx babel app.jsx --out-file app_compiled.js

app_compiled.js (with runtime: "automatic"):

"use strict";
var _jsxRuntime = require("react/jsx-runtime");
var element = /*#__PURE__*/(0, _jsxRuntime.jsx)("h1", {
children: "Hello, React World!"
});

If using the classic runtime ("runtime": "classic" or default before React 17), it would look like this, requiring React to be in scope:

"use strict";
// Assuming React is imported or globally available
var element = React.createElement("h1", null, "Hello, React World!");

For projects using TypeScript, @babel/preset-typescript allows Babel to strip TypeScript type annotations, enabling you to use Babel’s ecosystem for further transformations or bundling.

Installation:

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

Configuration (babel.config.json):

{
"presets": [
"@babel/preset-env", // For general JS features
"@babel/preset-typescript"
]
}

Important: Babel only performs type stripping for TypeScript. It does not perform type checking. You’ll still need to use the TypeScript compiler (tsc --noEmit) or an IDE with TypeScript support for actual type checking.

Create utils.ts:

function add(a: number, b: number): number {
return a + b;
}
const result: number = add(5, 10);

Transpile it:

npx babel utils.ts --out-file utils_compiled.js --extensions ".ts,.tsx,.js,.jsx"

utils_compiled.js:

"use strict";
function add(a, b) {
return a + b;
}
const result = add(5, 10);

The type annotations are removed, leaving plain JavaScript.

Using presets significantly simplifies Babel configuration, allowing developers to quickly set up transpilation for common JavaScript dialects and features. Always refer to the official Babel documentation for the latest information on presets and their options.