Upgrade to Babel 8
Refer users to this document when upgrading to Babel 8 from Babel 7. If you are a plugin developer or integration developer, please also check migration guide for integration.
If you are upgrading from Babel 6, please check here for Babel 7 migration guide.
All of Babel
Node.js support
All Babel 8 packages require Node.js ^16.20.0 || ^18.16.0 || >=20.0.0
.
We highly encourage you to use a newer version of Node.js (LTS v18) since the previous versions are not maintained. See nodejs/Release for more information.
This just means Babel itself won't run on older versions of Node. It can still output code that runs on old Node versions.
ESM only
Babel is now shipped in native ECMAScript modules. (#11701)
@babel/core
requirements
All presets and plugins require @babel/core@^8.0.0
as peer dependency.
@babel/eslint-parser
and @babel/eslint-plugin
The parser and plugin require eslint@^8.9.0
as peer dependency. (#15563)
Package Renames
The following packages has been renamed to -transform
as they have reached Stage 4 (#15614). The rename process has been landed in Babel 7.22 so you can start the migration prior to the upgrade.
Babel 7 | Babel 8 |
---|---|
@babel/plugin-proposal-async-generator-functions | @babel/plugin-transform-async-generator-functions |
@babel/plugin-proposal-class-properties | @babel/plugin-transform-class-properties |
@babel/plugin-proposal-class-static-block | @babel/plugin-transform-class-static-block |
@babel/plugin-proposal-duplicate-named-capturing-groups-regex | @babel/plugin-transform-duplicate-named-capturing-groups-regex |
@babel/plugin-proposal-dynamic-import | @babel/plugin-transform-dynamic-import |
@babel/plugin-proposal-export-namespace-from | @babel/plugin-transform-export-namespace-from |
@babel/plugin-proposal-json-strings | @babel/plugin-transform-json-strings |
@babel/plugin-proposal-logical-assignment-operators | @babel/plugin-transform-logical-assignment-operators |
@babel/plugin-proposal-nullish-coalescing-operator | @babel/plugin-transform-nullish-coalescing-operator |
@babel/plugin-proposal-numeric-separator | @babel/plugin-transform-numeric-separator |
@babel/plugin-proposal-object-rest-spread | @babel/plugin-transform-object-rest-spread |
@babel/plugin-proposal-optional-catch-binding | @babel/plugin-transform-optional-catch-binding |
@babel/plugin-proposal-optional-chaining | @babel/plugin-transform-optional-chaining |
@babel/plugin-proposal-private-methods | @babel/plugin-transform-private-methods |
@babel/plugin-proposal-private-property-in-object | @babel/plugin-transform-private-property-in-object |
@babel/plugin-proposal-unicode-property-regex | @babel/plugin-transform-unicode-property-regex |
Package Discontinued
@babel/runtime-corejs2
Please upgrade to @babel/runtime-corejs3
(#11751). After
you install the new runtime, please set the corejs
version to 3.
{
"plugins": ["@babel/transform-runtime", {
- corejs: 2
+ corejs: 3
}]
}
@babel/plugin-syntax-import-assertions
Please migrate to @babel/plugin-syntax-import-attributes
(#15536). After you replace the plugin, you should search and replace the following patterns in your codebase:
- import value from "module" assert { type: "json" };
+ import value from "module" with { type: "json" };
Syntax plugins
The following syntax plugins are no longer needed, you can safely remove them from your config and node modules:
@babel/plugin-syntax-async-functions
@babel/plugin-syntax-async-generators
@babel/plugin-syntax-bigint
@babel/plugin-syntax-class-properties
@babel/plugin-syntax-class-static-block
@babel/plugin-syntax-dynamic-import
@babel/plugin-syntax-exponentiation-operator
@babel/plugin-syntax-export-extensions
@babel/plugin-syntax-export-namespace-from
@babel/plugin-syntax-import-meta
@babel/plugin-syntax-json-strings
@babel/plugin-syntax-logical-assignment-operators
@babel/plugin-syntax-module-string-names
@babel/plugin-syntax-nullish-coalescing-operator
@babel/plugin-syntax-numeric-separator
@babel/plugin-syntax-object-rest-spread
@babel/plugin-syntax-optional-catch-binding
@babel/plugin-syntax-optional-chaining
@babel/plugin-syntax-private-property-in-object
@babel/plugin-syntax-top-level-await
@babel/plugin-syntax-trailing-function-commas
@babel/plugin-syntax-unicode-sets-regex
Configuration Changes
@babel/core
The root AMD/UMD/SystemJS options, namely
moduleIds
,getModuleId
,moduleRoot
,moduleId
andfilenameRelative
are moved to plugin options (#5473, #12724).Migration: Move these options to the module plugin, for example, if you are using
@babel/plugin-transform-modules-systemjs
:babel.config.jsmodule.exports = {
plugins: [
['@babel/plugin-transform-modules-systemjs', {
moduleIds: true,
moduleRoot: 'myApp',
getModuleId (name) {
return name + "suffix";
},
}],
],
};Adapt the example above if you are using
@babel/plugin-transform-modules-amd
or@babel/plugin-transform-modules-umd
. You can start the migration prior to Babel 8.0.If you are using
@babel/cli
and passing--module-ids
,--module-root
and--module-id
from command line, please create a Babel configbabel.config.js
and specify options there.
@babel/preset-env
includes
andexcludes
respect renamed package names (#15576)Migration: If
includes
orexcludes
contain any plugins mentioned in the Packages Renames section, change it to the new name. For example,babel.config.json{
"presets": [[
"@babel/preset-env",
{
- "includes": ["proposal-optional-chaining"]
+ "includes": ["transform-optional-chaining"]
}
]]
}
Remove
uglify
target (#12594)Migration: The
uglify
target had been deprecated since 7.0.0, if you still need this, use theforceAllTransforms
option.Removed syntax plugins can not be used in
includes
andexcludes
(#15810)Migration: You can safely remove them if you are using any of syntax plugins listed above in the
includes
andexcludes
options.
@babel/preset-react
Remove
useSpread
anduseBuiltIns
options (#12593)Migration: Babel 8 always compiles JSX spread elements to object spread:
input.jsx<div {...props}></div>
// transforms to
jsx("div", { ...props })If your app targets to modern browsers released after 2019, you can safely remove these options as object spread has less code footprint.
If your code needs to run in an environment which doesn't support object spread, you can either use
@babel/preset-env
(recommended) or@babel/plugin-transform-object-rest-spread
. If you want to transpileObject.assign
down, you also need to enable@babel/plugin-transform-object-assign
. In Babel 7.7.0, you can opt-in this behavior by using theuseSpread
option.Type check input options (#12460)
Migration: The preset will also report invalid option names. Refer to the docs and ensure valid usage.
Disallow
filter
option in automatic runtime (#15068)Migration: The
filter
option can only be used with theclassic
runtime. If you have switched toautomatic
runtime, you can safely remove this option. Otherwise please specifyruntime: "classic"
.
@babel/preset-typescript
Remove
isTSX
andallExtensions
options (#14955)Migration:
isTSX: true
andallExtensions: true
If you are already using
@babel/preset-react
,@babel/plugin-transform-react-jsx
or any other third-party jsx presets such as@vue/babel-preset-jsx
, and you want to transpile.tsx
files, you can safely remove these two options. Babel 8 will automatically handle.tsx
files using this preset and the other JSX plugin.babel.config.json{
"presets": [
["@babel/preset-react", { "runtime": "automatic" }],
- ["@babel/preset-typescript", { "allExtensions": true, "isTSX": true }]
+ ["@babel/preset-typescript"]
]
}If you want to transpile files other than
.tsx
, such as.vue
, useignoreExtensions: true
:babel.config.js{
overrides: [{
include: /\.vue$/,
presets: [
['@babel/preset-typescript', {
- allExtensions: true, isTSX: true
+ ignoreExtensions: true
}]
]
}]
}If you want to preserve the JSX format but transpile the TypeScript part, use
ignoreExtensions: true
and add@babel/plugin-syntax-jsx
toplugins
.isTSX: false
andallExtensions: true
Use
ignoreExtensions: true
, see the example above.isTSX: false
andallExtensions: false
You can safely remove them.
Remove
allowDeclareFields
option (#12461)Migration: Remove the option from your config, since it's now enabled by default. Previously
allowDeclareFields
enables transforming thedeclare
syntax introduced in TypeScript 3.7, in Babel 8 we support the syntax without such a flag. See also the compilation changes section.Type check input options (#12460)
Migration: The preset will also report invalid option names. Refer to the docs and ensure valid usage. For example,
runtime
is not a validpreset-typescript
option and thus should be removed.
@babel/plugin-transform-typescript
Remove
allowDeclareFields
option (#12461)Migration: Remove the option from your config.
@babel/plugin-syntax-typescript
Remove
isTSX
option (#14955)Migration: If you are using
isTSX: true
, remove this option and add@babel/plugin-syntax-jsx
toplugins
:"babel.config.json{
"plugins": [
- ["@babel/plugin-syntax-typescript", { "isTSX": true }]
+ ["@babel/plugin-syntax-typescript"]
+ ["@babel/plugin-syntax-jsx"]
]
}If you are using
isTSX: false
, you can safely remove them.
@babel/preset-flow
Remove
allowDeclareFields
option (#12457)Migration: Remove the option from your config, since it's now enabled by default. Previously
allowDeclareFields
enables transforming thedeclare
syntax introduced in Flow 0.120.0, in Babel 8 we support the syntax without such a flag. See also the compilation changes section.Type check input options (#12460)
Migration: The preset will also report invalid option names. Refer to the docs and ensure valid usage.
@babel/plugin-transform-flow-strip-types
Remove
allowDeclareFields
option (#12457)Migration: Remove the option from your config. You will probably be fine with the new behaviour.
@babel/parser
Remove
estree
plugin optionclassFeatures
(#13752)Migration: Remove the option from your config, since it's now enabled by default. Previously the
classFeatures
plugin enables@babel/parser
to produce class properties AST compatible with ESLint 8, following the ESTree specification. In Babel 8 theeslint-parser
only works with ESLint 8 and above.
@babel/generator
Remove
jsonCompatibleStrings
generator option (#9943, #12477)Migration:
@babel/generator
allows to specify options for jsesc, a library used to escape printed values. If you are using thejsonCompatibleStrings
option, you can replace it withjsescOption: { json: true }
.
@babel/eslint-parser
Remove
allowImportExportEverywhere
option (#13921)Migration: Use
babelOptions.parserOpts.allowImportExportEverywhere
instead..eslintrc{
"parser": "@babel/eslint-parser",
"parserOptions": {
- "allowImportExportEverywhere": true,
+ "babelOptions": {
+ "parserOpts": {
+ "allowImportExportEverywhere": true
+ }
+ }
}
}
parserOpts.allowSuperOutsideMethod
defaults tofalse
(#13921)Migration: If you want to restore to Babel 7 behaviour, set
babelOptions.parserOpts.allowSuperOutsideMethod
totrue
.allowReturnOutsideFunction
is inferred fromecmaFeatures.globalReturn
(#13921)Migration: If you want to enable
allowReturnOutsideFunction
, setecmaFeatures.globalReturn
totrue
..eslintrc{
"parser": "@babel/eslint-parser",
"parserOptions": {
"ecmaFeatures": {
"globalReturn": true
}
}
}
@babel/plugin-transform-modules-systemjs
Require
@babel/plugin-transform-dynamic-import
when transformingimport()
to SystemJS (#12700)Migration: Add
@babel/plugin-transform-dynamic-import
to your config: you can already do it in Babel 7. If you are using@babel/preset-env
, you don't need to do anything.babel.config.js.diff{
"plugins": [
+ "@babel/plugin-transform-dynamic-import",
"@babel/plugin-transform-modules-systemjs",
]
}Notes: All the other plugins which support dynamic import (
transform-modules-commonjs
andtransform-modules-amd
) require the separate plugin since it was introduced. We couldn't change it fortransform-modules-systemjs
because that package did already support dynamic import.
@babel/plugin-proposal-decorators
Only support
legacy
and2023-05
. The plugin now requires aversion
option (#12712, #15676)Migration: You should migrate to the latest version of the proposal
"2023-05"
, if you are using the"2018-09"
or you have not specified aversion
option.babel.config.json{
"plugins": [
["@babel/plugin-proposal-decorators", {
- "decoratorsBeforeExport": true,
- "version": "2018-09",
+ "version": "2023-05"
}]
]
}The syntax is the same, but you will need to rewrite your decorator functions. The spec repo provides comparison between the latest version and the
2018-09
version. You can already migrate since Babel 7.22.0, using the"version": "2023-05"
option of@babel/plugin-proposal-decorators
.Although Babel 8 still supports the
legacy
version, it is advisable to migrate to the2023-05
version regardless: both Babel 8 and TypeScript 5.0 support the2023-05
version, while there are a few behaviour differences in thelegacy
version between Babel andtsc
's implementation.
@babel/node
- The
-gc
and-d
command-line flags have been removed (#15956) Migration: Use the--expose-gc
and--inspect
Node.js flags respectively. Note that although-d
was short for--debug
, the latter has been deprecated since Node.js 7.7.0.
Compilation Changes
Default target
Use browserslist's
defaults
as default compilation target (#12989, #15551).Migration: If you are already using
targets
or have a.browserslist
config file, this change won't affect you. Otherwise, you'll probably be fine with the new behavior since the browserslist'sdefautls
covers most modern browsers.If you need to support legacy browsers, create a
.browserlist
config.
@babel/preset-env
Enable the
bugfixes
option by default (#13866)Migration: You will probably be fine with the new behaviour as Babel now tries to compile the broken syntax to the closest non-broken modern syntax supported by your target browsers. If anyhow you want to restore the Babel 7 behaviour, you can specify
bugfixes: false
.
JSX
Use the new JSX implementation by default (#12630)
Migration: If you are using a modern version of React or Preact, it should work without any configuration changes. Otherwise, you can pass the
runtime: "classic"
option to@babel/preset-react
or@babel/plugin-transform-react-jsx
to be explicit about your usage ofcreateElement
(or the equivalent function in other libraries).
Transforms JSX spread properties using object spread (#12593)
Migration: See the Configuration changes / preset-react section.
Disallow sequence expressions inside JSX attributes (#12447)
Migration: Find and replace the following code patterns. You can start the migration prior to Babel 8:
input.jsx- <p key={foo, bar}></p> // Invalid
+ <p key={(foo, bar)}></p> // ValidDisallow
{
,}
,<
and>
in JSX text (#12451)Migration: Use
{'{'}
,{'}'}
,{'<'}
and{'>'}
instead. Find and replace the following code patterns. You can start the migration prior to Babel 8:input.jsx- <p>">" is greater than.</p>
+ <p>"{'>'}" is greater than.</p>Notes: This is technically a spec compliance fix becase the JSX specification already forbids them. However, we have chosen to postpone it until Babel 8 because it could break someone's code.
TypeScript
Preserve uninitialized class fields (#12461)
Migration: Use the new
declare
syntax, introduced in TypeScript 3.7, if you don't want fields to be initialized toundefined
:input.tsclass A {
foo: string | void; // initialized to undefined
declare bar: number; // type-only, will be removed
}
Flow
Preserve uninitialized class fields (#12457)
Migration: Use the new
declare
syntax, introduced in Flow 0.120, if you don't want fields to be initialized toundefined
:input.jsclass A {
foo: string | void; // initialized to undefined
declare bar: number; // type-only, will be removed
}
Misc
Output non-ASCII characters as-is in string literal (#12675)
If you are using any one of
@babel/cli
, WebPack, Rollup, create-react-app or other Node.js powered bundlers, the transformed code is always encoded withutf-8
and your app will not be affected. The issue only affects if you are manually calling thebabel.transform
API and your web server is not serving js files in theutf8
encoding.Migration: Ensure your server is always serving js files in the
utf8
encoding. If you can not control the server output, specify thecharset
attribute of thescript
tag in the html files.<script charset="utf-8" src="your-app.js"></script>
You can also restore to the Babel 7 behaviour by
babel.config.js{
generatorOpts: {
jsescOption: {
minimal: false
}
}
}