
What is (0, foo)() in webpack/Babel-compiled code
Why Babel and webpack-compiled code wraps some function calls in (0, ...)(), and what the comma operator has to do with the value of this.
Code that looks wrong but isn’t
Open the DevTools on a site built with webpack or Next.js, or just inspect Babel’s output, and you’ll find something like this:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _utils = require("./utils");
(0, _utils.doSomething)();
That (0, _utils.doSomething)() looks like an absurdly convoluted way to simply write _utils.doSomething(). It’s not a bundler bug, and it’s not randomly generated code either: it’s a precise choice made to faithfully reproduce the behavior of native ES modules.
The comma operator, briefly
Before getting to the “why,” it’s worth reviewing what the comma operator (,) does when used as an expression: it evaluates every item in the sequence from left to right and returns only the value of the last one.
let x = (1, 2, 3);
console.log(x); // 3
In the earlier example, (0, _utils.doSomething) evaluates 0, discards it, and returns _utils.doSomething — that is, the reference to the function. So far, the exact same reference you’d get by writing _utils.doSomething directly. The difference lies in how that reference is then called.
The real reason: detaching the value of this
When you call a method as object.method(), JavaScript binds this inside method to object, the thing to the left of the dot. Try this example:
const module = {
name: "module",
getThis() {
return this;
},
};
module.getThis(); // this === module
const ref = module.getThis;
ref(); // this === undefined (in strict mode)
Assigning the function to a variable and then calling it “detaches” it from module: this goes back to being undefined (in strict mode) instead of module. The comma expression achieves exactly this result, but inline, without introducing an intermediate variable:
(0, module.getThis)(); // this === undefined, just like with the variable
Why Babel/webpack do this on purpose
In the ES modules spec, when you import a function with import { foo } from './module' and call it as foo(), this inside foo is always undefined: there’s no implicit binding to the module object it was imported from.
The problem is that Babel compiles import/export down to require/exports for CommonJS compatibility. If it naively translated foo() into _module.foo(), the behavior would silently change: that syntax binds this to the _module object (the imported module’s exports object), which the ES spec explicitly forbids.
To avoid this discrepancy, Babel generates (0, _module.foo)(): it grabs the reference to the function without calling it in _module’s context, then invokes it “detached,” faithfully reproducing the native ES module behavior even in code transpiled to CommonJS.
ℹ️ In short
It’s not a strange way of writing a function call: it’s how Babel guarantees that this inside
the imported function stays undefined, exactly as a real native ES module would.
Where you’ll run into it
Basically every time you inspect Babel-compiled code (webpack, Next.js, Create React App, and plenty of other Babel-based toolchains) that imports a function from another module and calls it directly, rather than calling it as a method on an object. It’s the same kind of “obscure syntax found in the code” already covered in javascript:void(0) and !function()(): not a mistake, but a precise trick with a technical purpose.

Co-Founder & CTO at PAPION. Senior full-stack engineer specializing in React, TypeScript, Node.js, and application security.