Centralizing Babel Helpers with @babel/plugin-transform-runtime
Babel duplicates helper functions in every file by default. @babel/plugin-transform-runtime moves those helpers to shared imports from @babel/runtime, reducing bundle size and making polyfills explicit.
18 Sept 2025, 02:55 UTC

When you transpile modern JavaScript with Babel, each file that uses features like async/await or object spread gets its own copy of helper functions such as _extends or _asyncToGenerator. This duplication inflates the bundle and makes tree‑shaking less effective.
How @babel/plugin-transform-runtime solves the duplication
The plugin rewrites those helper definitions into imports from the shared @babel/runtime package. With corejs: 3 enabled it also rewrites core‑js usage to imports from @babel/runtime/core-js, pulling in only the polyfills needed for your declared targets.
Worked example: configuring the plugin for a library that targets both Node ESM and browsers
First add the plugin as a dev dependency and the runtime as a production dependency.
npm install --save-dev @babel/plugin-transform-runtime
npm install --save @babel/runtimeCreate a .babelrc.json (or babel.config.js) with the plugin configuration:
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": 3,
"helpers": true,
"regenerator": true,
"useESModules": true
}
]
]
}When useESModules is true the plugin emits ES module imports; set it to false for CommonJS output. After building, inspect the generated files – you should see import statements like:
import _extends from "@babel/runtime/helpers/esm/extends";
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
instead of the helper functions being inlined in each module. That indicates duplication has been removed.
Trade‑offs and limitations
The plugin only rewrites helpers; it does not polyfill language features that need full runtime support on their own. You must still configure core-js (or another polyfill) for features like Promise or Array.prototype.flat if your targets lack them.
A loose mode exists that can shrink the emitted code further, but it may change behavior relative to the strict ECMAScript specification. Use it only after testing that your code does not rely on the exact semantics.
Because helpers become runtime imports, you must ship @babel/runtime with your application. Forgetting to add it to production dependencies leads to reference errors at runtime.
Actionable checklist
- Add @babel/plugin-transform-runtime as a dev dependency and @babel/runtime as a production dependency.
- Configure the plugin with corejs: 3 (or the version matching your core‑js needs) and set helpers and regenerator as required.
- Match useESModules to your module system (true for ESM, false for CJS).
- Build and verify that helper imports come from @babel/runtime instead of being duplicated.
- Keep @babel/runtime in production and test the bundle in the oldest target environment you support.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.