Babel 8.0 Migration Guide: ESM-Only, TypeScript Types, Drop ES5
Guide · Updated 2026

Babel 8.0 Migration guide:
ESM-Only, TypeScript Types, No More ES5 Default

After 8 years since Babel 7, Babel 8 is here — and it's a modernization release, not a feature drop. ESM-only packages, TypeScript types for everything, and updated defaults that reflect the modern JavaScript ecosystem. Here's exactly what changed and how to migrate your project.

Oleg Maximov June 19, 2026 12 min read

Introduction

On June 16, 2026, the Babel team released Babel 8.0.0 — the first major version bump in 8 years. This is not a feature release. Babel 8 contains no new transforms, no new parser features, and no new proposals over what Babel 7 already supports. Instead, it's a modernization release that cleans up 8 years of accumulated technical debt and pushes the JavaScript ecosystem forward.

Babel's usage has exploded over the past 8 years: from 1.7 million weekly downloads in 2018 to 651 million weekly downloads in June 2026. With that scale comes enormous responsibility — even minor breaking changes can block hundreds of thousands of developers. The Babel team has taken an exceptionally careful approach, with a long beta period (the first alpha was published in 2023) and a multi-year deprecation cycle for changes like the loose option.

Major Changes at a Glance

Here's what Babel 8 changes compared to Babel 7:

Below I'll walk through each change in detail, with migration steps and code examples.

1. ESM-Only Packages

The biggest structural change in Babel 8 is that all Babel packages now ship as ES modules only. This applies to @babel/core, @babel/preset-env, @babel/parser, @babel/cli, and every other official package.

Why? With require(esm) now supported in all active LTS versions of Node.js, the ESM-only change is a natural step. It lets the Babel team modernize their own codebase, reduce package sizes, and simplify their build pipeline — while not breaking projects that still use CommonJS in application code.

What does this mean for your project?

If you use Babel programmatically (e.g., require('@babel/core') in a CommonJS file), you have two options:

// Before (Babel 7, CJS):
const babel = require('@babel/core');
babel.transformSync(code, options);

// After (Babel 8, async import in CJS):
const babel = await import('@babel/core');
const result = await babel.transformAsync(code, options);

// After (Babel 8, ESM project):
import * as babel from '@babel/core';
const result = await babel.transformAsync(code, options);

Note: If you only use Babel through your build tool (webpack, Vite, or a framework like Next.js), the bundler or framework handles this internally. You probably don't need to change anything.

Node.js version requirements

Babel 8 requires Node.js 22, 24, 26, or newer. Node.js 20 and 25 reached end-of-life earlier in 2026 and will not receive further security fixes. If you're still on an older Node.js version, upgrade first, then migrate to Babel 8.

2. TypeScript Types for All Packages

Babel 8 ships first-party TypeScript type definitions (.d.ts files) for every official Babel package. This means you no longer need to install @types/babel__* packages from DefinitelyTyped — the types come directly from the Babel source, so they're always in sync with the code.

// Before — needed separate types:
npm install @babel/core @types/babel__core

// After — types ship with the package:
npm install @babel/core
// Types are included — use them directly:
import { transformAsync, TransformOptions } from '@babel/core';

This is a quality-of-life improvement for TypeScript users. The Babel team has been maintaining their own types internally for years, and now they're shipping them to users. The types cover the full public API: core, parser, generators, preset-env, and all official plugins and presets.

3. No More ES5 Default

This is the change that will affect the most projects. In Babel 7, @babel/preset-env defaulted to compiling everything down to ES5 — the level of Internet Explorer 11. In Babel 8, preset-env defaults to Browserslist defaults, which currently targets approximately ES2023.

What this means in practice: less code is compiled away. Features like async/await, class syntax, arrow functions, for...of, and template literals are no longer downleveled by default. Your bundles get smaller and your build times get faster.

// Babel 7 default: compiles everything to ES5
// Babel 8 default: uses browserslist defaults (~2% market share)

// If you still need ES5 support, set targets explicitly:
// babel.config.json
{
  "presets": [
    ["@babel/preset-env", {
      "targets": "> 0.25%, ie 11"
    }]
  ]
}

Similarly, @babel/preset-env now outputs ES modules by default instead of CommonJS. This aligns with modern bundlers and runtimes. If you need CommonJS output, you can set sourceType: "commonjs" in your config (this option was added in Babel 7.28).

Migration tip: Before upgrading to Babel 8, build your project with targets: "defaults" (which is what browserslist defaults resolves to) while still on Babel 7. Verify that your supported browsers can handle the reduced output. If the build output still works in your target environments, Babel 8 will be a seamless upgrade for you.

4. loose and spec Deprecated — Use Assumptions

For years, Babel supported loose and spec options to trade off between spec compliance and output size/performance. The problem: it was often unclear what these options actually did. A developer setting loose: true on preset-env might not realize it affected everything from class fields to computed properties to iterables.

In Babel 8, loose and spec are removed from @babel/preset-env and deprecated from individual plugins. The replacement is assumptions — a fine-grained system introduced in Babel 7.13 that lets you control exactly which spec deviations to allow.

// Before (Babel 7):
{
  "presets": [
    ["@babel/preset-env", { "loose": true }]
  ]
}

// After (Babel 8) — use assumptions instead:
{
  "assumptions": {
    "setPublicClassFields": true,
    "privateFieldsAsProperties": true,
    "noDocumentAll": true,
    "iterableIsArray": true
  },
  "presets": [
    ["@babel/preset-env"]
  ]
}

Migrate before upgrading. Assumptions have been supported since Babel 7.13.0, so you can switch from loose/spec to assumptions while still on Babel 7, then upgrade to Babel 8 when ready. The Babel docs have a mapping table showing which assumption corresponds to each previously-loose behavior.

5. Polyfill Injection Moves to Separate Packages

Babel 8 removes the corejs and useBuiltIns options from @babel/preset-env and @babel/plugin-transform-runtime. These are replaced by babel-plugin-polyfill-corejs3, a dedicated polyfill injection plugin from the babel-polyfills project.

// Before (Babel 7):
npm install core-js@3
// babel.config.json
{
  "presets": [
    ["@babel/preset-env", {
      "useBuiltIns": "usage",
      "corejs": "3.38"
    }]
  ]
}

// After (Babel 8):
npm install core-js@3 babel-plugin-polyfill-corejs3
// babel.config.json
{
  "plugins": [
    ["polyfill-corejs3", {
      "method": "usage-global",
      "version": "3.38"
    }]
  ],
  "presets": [
    ["@babel/preset-env"]
  ]
}

The new plugin provides more granular control over polyfill injection. You can choose between usage-global (inject polyfills as global imports, matching the old useBuiltIns: "usage" behavior) and usage-pure (inject without globals, matching the old runtime approach).

Migrate this before upgrading to Babel 8. The standalone babel-plugin-polyfill-corejs3 works with Babel 7 already, so you can swap out your useBuiltIns/corejs configuration while still on Babel 7.

Other Notable Changes

Deprecated and removed items

Babel 8 drops support for several long-deprecated features:

Internal improvements

The Babel team used the major release to clean up internal code structure. While invisible to most users, these changes make Babel easier to maintain and contribute to:

Migration Checklist

Here's a step-by-step plan to migrate your project from Babel 7 to Babel 8:

Phase 1: Prepare (still on Babel 7)

  1. Upgrade Node.js to v22, v24, or v26 if you haven't already.
  2. Replace loose/spec options with assumptions in your Babel config.
  3. Replace useBuiltIns/corejs with babel-plugin-polyfill-corejs3.
  4. Test your build with targets: "defaults" to verify the new defaults work for your project.
  5. Update any @types/babel__* packages — you'll remove them after upgrading.

Phase 2: Upgrade to Babel 8

  1. Update all @babel/* packages to ^8.0.0.
  2. If using CJS programmatic API, switch to dynamic import() or convert to ESM.
  3. Remove @types/babel__* packages — types are now included.
  4. Remove corejs/useBuiltIns from preset-env config if you migrated in Phase 1.
  5. Remove loose/spec from preset-env config if you migrated in Phase 1.

Phase 3: Verify

  1. Run babel --version — should print 8.0.0.
  2. Build your project and check for errors.
  3. Run your test suite.
  4. Verify the output bundle works in your target browsers.
  5. If anything breaks, review the official upgrade guide.

Comparison: Babel vs Alternative Compilers

The JavaScript compilation landscape has diversified since Babel 7 launched. While Babel remains the most popular transpiler by a wide margin (651M weekly downloads), it's worth understanding how the alternatives position themselves. For a broader view of the JavaScript tooling ecosystem, check my guide to the Zod Compiler, which takes a similar build-time optimization approach.

Feature Babel 8 SWC Oxc
Language JavaScript (ESM) Rust Rust
Plugin ecosystem Hundreds of plugins, 8+ years of maturity Growing, but smaller Early stage
Speed Fast (JS) Very fast (Rust) Very fast (Rust)
TypeScript support Stripping only, no type checking Stripping + some type-aware transforms Stripping only
TypeScript types bundled Yes (new in Babel 8) No (separate @types) In progress
ESM distribution Yes (new in Babel 8) Yes Yes
LTS / stability Very high, 8 years of proven reliability High, widely adopted Newer, maturing

For most projects, Babel remains the safest choice due to its massive plugin ecosystem, proven stability, and the new TypeScript type definitions. SWC and Oxc are excellent for speed-critical pipelines where Rust performance matters more than plugin availability.

The State of Babel: Usage and Funding

Babel's growth has been staggering. From 1.7 million weekly downloads in 2018 to 651 million weekly downloads in June 2026 — that's a 383× increase. The project has doubled its download count in the last year alone. This is not a dying project; it's the most popular JavaScript compiler in the world by a vast margin.

However, the Babel team faces a funding challenge. Donations through OpenCollective and GitHub Sponsors have been steadily decreasing even as usage skyrockets. The Babel core team — currently consisting of Huáng Jùnliàng, liuxingbaoyu, and Nicolò Ribaudo — relies on support from the Sovereign Tech Agency (Germany) and Igalia, but those funding sources are time-limited.

If your organization relies on Babel (and there's a good chance it does — directly or through a framework), consider supporting the project. At 651M weekly downloads, even a tiny contribution rate would secure the project's future for years.

Babel 7 Sunset Timeline

Babel 7 will continue to receive security fixes only until June 2027. No new features or non-security bug fixes will be backported. If you absolutely cannot migrate within a year, plan your migration carefully — but don't wait until the last minute. The ESM-only change and the TypeScript types are strong incentives to move to Babel 8 sooner rather than later.

FAQ

What are the biggest breaking changes in Babel 8?
The three biggest changes are: (1) Babel ships as ESM only — you need Node.js 22+ and must use import instead of require() for programmatic usage. (2) @babel/preset-env no longer compiles to ES5 by default — it uses browserslist defaults (~ES2023). (3) loose/spec options are removed from preset-env in favor of assumptions. All three can be migrated incrementally while still on Babel 7.
Can I still compile to ES5 with Babel 8?
Yes, Babel 8 fully supports ES5 output — you just need to set explicit targets in your preset-env configuration. The change is only about the default, not about removing the capability. If your project still needs to support IE11 or other legacy browsers, you can target them explicitly: targets: "> 0.25%, ie 11".
What Node.js version do I need for Babel 8?
Babel 8 requires Node.js 22, 24, 26, or newer. Node.js 20 and 25 have reached end-of-life and are not supported. The ESM requirement means your runtime must support import natively — all listed versions do. If you're still on an older Node.js, upgrade first. For the latest on Node.js release changes, see my guide on the new Node.js release schedule.
How do I migrate from loose/spec options to assumptions?
The Babel docs have a complete mapping table for each loose option to its equivalent assumption. For example, loose: true for classes maps to assumptions.setPublicClassFields = true. You can make this change while still on Babel 7 — assumptions have been supported since Babel 7.13. Do this migration first, then upgrade to Babel 8.
What happened to useBuiltIns and corejs options?
These have been removed from @babel/preset-env and @babel/plugin-transform-runtime in Babel 8. The replacement is babel-plugin-polyfill-corejs3, which gives you more control over polyfill injection. You can choose between usage-global (global polyfills, like the old useBuiltIns: "usage") and usage-pure (pure imports without globals). Install it separately and migrate before upgrading to Babel 8.
Is Babel 7 still supported?
Yes, Babel 7 will receive security fixes until June 2027 — one year after the Babel 8 release. No new features or bug fixes will be backported unless there's significant community demand. The Babel team recommends planning your migration within this security window.
Does Babel 8 include any new features?
No. Babel 8 contains zero new features over Babel 7. All the transform plugins and parser features that were added in Babel 7.23 through 7.29 are included, but the major version bump is purely about architectural modernization: ESM, TypeScript types, and updated defaults. The Babel team explicitly states this is not a feature release — it's about making Babel ready for the next 8 years.

Ready to Migrate?

Babel 8 is a net positive for the JavaScript ecosystem. The ESM-only packaging, bundled TypeScript types, and modern defaults all point in the right direction. The migration is not trivial — it requires updating configs, possibly changing how you import Babel, and verifying your output targets. But the 12-month security window for Babel 7 gives you plenty of time to plan and execute the migration carefully.

If you're working on a complex build pipeline and need help planning this migration or evaluating how it affects your project's toolchain, get in touch. I help teams migrate their build configurations and can provide a clear migration path tailored to your stack.

Contact

Let's discuss your project

Need help migrating your build pipeline to Babel 8 or modernizing your JavaScript toolchain? I provide free initial consultations.