Stopping Helper Bloat: Using @babel/plugin-transform-runtime
Stop duplicating helper functions in your JS bundles. Learn how @babel/plugin-transform-runtime reduces bundle size and prevents global namespace pollution for libraries.
15 Feb 2026, 11:11 UTC

The Hidden Cost of Babel Helpers
When Babel transpiles modern JavaScript (ES6+) into a version compatible with older browsers, it often needs to implement complex logic—like classes or object spreading—using simpler functions. These are called helpers.
By default, Babel injects these helpers into every single file that requires them. If you have 100 files using the spread operator, Babel defines the _extend helper 100 times across your bundle. In a large application, this duplication creates significant bloat, increasing your final bundle size and slowing down page load times.
The solution is @babel/plugin-transform-runtime. Instead of inlining the helper code, this plugin tells Babel to import the helper from a shared module, ensuring each piece of logic is defined exactly once.
Reducing Bundle Size and Global Pollution
Beyond reducing duplication, the transform-runtime plugin solves a critical problem for library authors: global namespace pollution. Standard polyfills (like those from core-js) typically modify the global prototype. For example, adding Array.prototype.includes globally might break a consumer's application if they rely on a different version of that method.
The runtime plugin replaces these global references with aliased versions. Instead of modifying window.Promise, it imports a sandboxed version of Promise from the runtime package. This allows your code to use modern features without risking side effects in the environment where your library is installed.
Implementation and Configuration
To implement this, you need two distinct packages: the plugin for the build process and the runtime for the production code.
1. Install dependencies
Run the following in your terminal. Note that the runtime must be a dependency, not a devDependency, because the final bundled code will reference it at runtime.
# Install the plugin as a development dependency
npm install --save-dev @babel/plugin-transform-runtime
# Install the runtime as a production dependency
npm install @babel/runtime
2. Configure .babelrc or babel.config.json
Add the plugin to your configuration file. You can customize whether it handles regenerator (async/await) and core-js polyfills.
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"corejs": false,
"helpers": true,
"regenerator": true
}
]
]
}
Configuration Breakdown
helpers: true: Replaces inline helpers with imports from@babel/runtime.regenerator: true: Replaces the globalregeneratorRuntime(used for async/await) with a modular import.corejs: false: When false, it only handles helpers. Setting this to2or3enables the sandboxed polyfilling mentioned earlier.
Verifying the Result
To confirm the plugin is working, you can inspect your transpiled output before it is minified. Search for a common helper like _extend or _classCallCheck.
Without the plugin: You will see the function definition repeated in multiple files:
function _extend() { ... }
// ... rest of file logic
With the plugin: You will see a module import at the top of the file:
import _extend from "@babel/runtime/helpers/extends";
// ... rest of file logic
Trade-offs and Limitations
While this plugin is highly effective, it is not a universal "win." If your application is small and only uses one or two helpers, the overhead of adding a new dependency and the import statements might actually increase the bundle size slightly.
Additionally, if you are building a standalone application (rather than a library) and already have a global polyfill strategy (like @babel/preset-env with useBuiltIns: 'entry'), enabling corejs in the runtime plugin can lead to duplicate polyfills. In such cases, use the runtime plugin only for helpers and regenerator, leaving the global polyfills to your preset configuration.
Summary Checklist
- Ensure
@babel/runtimeis independencies. - Use
corejs: falsefor apps with existing global polyfills. - Use
corejs: 3for libraries to avoid polluting the consumer's global scope. - Verify the output contains
importstatements rather than repeated function definitions.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.