7.28.0 Released: `babel.config.ts`, explicit resource management, and discard binding proposal
Babel 7.28.0 is out!
This release includes support for babel.config.ts
and babel.config.mts
, the ES2026 Explicit Resource Management feature, the discard binding proposal, and the sourceType: "commonjs"
option.
You can read the whole changelog on GitHub. If you are already using Babel 8 beta, all the new 7.28.0 features are included in v8.0.0-beta.1.
If you or your company want to support Babel and the evolution of JavaScript but aren't sure how, you can donate to us on our Open Collective and, better yet, work with us on the implementation of new ECMAScript proposals directly! As a volunteer-driven project, we rely on the community's support to fund our efforts in supporting the wide range of JavaScript users. Reach out at team@babeljs.io if you'd like to discuss more!
Highlightsโ
Native support for babel.config.ts
and babel.config.mts
(#17392)โ
Babel now supports babel.config.ts
and babel.config.mts
natively. We recommend using Node.js 24 for the best results.
If you are using Babel 8.0.0-beta.1, you can import typings directly from @babel/core
and use them in your Babel config:
// Requires Babel 8.0.0-beta.1 or above
import type { ConfigAPI, InputOptions } from "@babel/core";
export default function babelConfig(api: ConfigAPI): InputOptions {
return {
assumptions: {
noDocumentAll: true
},
presets: [
[
"@babel/preset-env",
{
targets: {
node: "current",
},
},
],
"@babel/preset-typescript",
],
};
}
Explicit resource management enabled by default (#17346, #17355)โ
{
using handlerSync = openSync();
await using handlerAsync = await openAsync();
// handlerSync and handlerAsync will be disposed when the block exits
}
Explicit resource management, which was conditionally approved for Stage 4 during the May 2025 TC39 meeting, is now enabled by default in @babel/preset-env
and @babel/parser
.
If you were using the @babel/plugin-proposal-explicit-resource-management
plugin and @babel/preset-env
, you can now remove the plugin from your config.
If you used the explicitResourceManagement
parser plugin, you can remove it from your config.
Discard binding (#17276)โ
Babel supports transforming the discard binding proposal. Now you can use the void
binding to indicate an unused variable or parameter:
{
using void = new AcquireLock(mutex);
// The mutex lock will be automatically disposed when the block exits
}
// A customized JSON serializer with bigint support
// The first parameter of the replacer is unused
JSON.stringify(input, (void, value) => {
if (typeof value === "bigint") {
return value.toString();
} else {
return value.toJSON();
}
});
// Get a clone of the input object without property `z`
const { z: void, ...obj } = { x: 1, y: 2, z: 3 };
obj; // { x: 1, y: 2 }
You can enable it by adding the @babel/plugin-proposal-discard-binding
plugin to your Babel config.
export default {
plugins: [
["@babel/plugin-proposal-discard-binding", { syntaxType: "void" }]
]
}
Note that the proposal might still change to use a different syntax: as such, the syntaxType
option is required and currently its only valid value is "void"
.
sourceType: "commonjs"
(#17390)โ
The "commonjs"
mode indicates that the code should be run in a CommonJS environment such as Node.js. It is similar the "script"
mode, but it allows return
, new.target
, and using
/await using
declarations are allowed at the top level.
export default {
// Specify commonjs sourceType for all `*.cjs` sources
overrides: [
{
test: "*.cjs",
sourceType: "commonjs"
}
]
}
You should use sourceType: "commonjs"
when using CommonJS-specific syntax, and sourceType: "script"
when writing non-module <script>
s.