The Replacement ■ Episode 02
Here is the entire setup for loading JavaScript modules in a browser in 2026:
<script type=”module”>
That is it. No npm install. No webpack.config.js.
No 847 MB node_modules directory. No Babel transpilation stage.
No loader chain. No plugin ecosystem. One attribute on a script tag, and the
browser does what it has known how to do since 2018.
The question is not whether this works. The question is why, eight years later, the industry still behaves as though it does not.
The Timeline Nobody Checked
The history is brief and instructive. In 2015, HTTP/2 shipped with multiplexing: the ability to send hundreds of requests over a single TCP connection without the head-of-line blocking that made HTTP/1.1 concatenation necessary. The “too many requests” argument, the foundational justification for bundling everything into a single file, became a historical footnote. Nobody sent flowers.
In 2017, ES Modules landed in Chrome 61 and Safari 11. Firefox 60 followed in
May 2018. Edge 16 completed the set. The import and
export keywords became native browser primitives. Not polyfilled.
Not transpiled. Understood.
The browser, in other words, has understood JavaScript modules for the better part of a decade. The build pipeline (npm, Webpack, Babel, the entire orchestrated ceremony of transpilation and bundling) is not solving a current problem. It is solving a 2012 problem, in 2026, at 2026 prices.
The Anatomy of the Replacement
The traditional JavaScript workflow requires four interlocking systems: a package manager to fetch code, a bundler to concatenate it, a transpiler to downgrade it, and a configuration layer to make the other three cooperate. Native ES Modules replace the entire chain with a browser-native mechanism.
The <script type=”module”> attribute tells the browser
to treat the file as an ES Module. The browser resolves import statements,
fetches the dependencies, and executes them in the correct order. It has done this,
reliably, across all major browsers, for eight years. The
global support
stands at 98%, which is higher than the support for several CSS properties that
nobody hesitates to ship.
The Phantom Objection
The most common objection arrives on cue: “But what about performance? Loading fifty individual files is slower than loading one bundle.”
This was true in 2014. It has not been true since 2015.
HTTP/2 multiplexing allows hundreds of requests to travel in parallel over a single connection. There is no connection-per-request overhead. There is no head-of-line blocking. The protocol was specifically designed to make the concatenation argument obsolete, and it succeeded. Eleven years ago.
Moreover, the browser caches individual modules. Change one file, and the browser reloads precisely that file. The other forty-nine remain cached. With a bundled application, changing one line of code invalidates the entire bundle. The user downloads everything again. This is not a theoretical disadvantage. It is a measurable one, on every deployment, for every user.
What You Lose
Honesty demands an itemisation of the costs. Abandoning the build pipeline means abandoning several things the industry has grown accustomed to.
The npm ecosystem. 2.1 million packages, the greatest
unaudited code dump on Earth. You lose access to is-odd, the package
that checks whether a number is odd (400,000 weekly downloads at its peak, for a
function that is one line of arithmetic). You lose the convenience of
npm install and gain the inconvenience of understanding what your
dependencies actually do. Whether this is a loss depends on your relationship
with the
left-pad
incident of 2016, in which eleven lines of code brought down build systems
across the industry.
Build-time optimisation. Tree-shaking, dead code elimination, minification: these are genuine benefits when your application ships five hundred modules. For a project with thirty modules, the optimisation removes kilobytes. The build pipeline that performs the optimisation adds minutes. The arithmetic is unflattering.
TypeScript. Without a build step, .ts files do not
reach the browser. This is a genuine constraint for TypeScript projects. It is
not a constraint for JavaScript projects, which is most of the web.
What You Gain
Zero build step. Save the file. Reload the browser. The feedback loop is instantaneous because there is nothing between the code and the execution environment. No watcher. No compilation. No bundle invalidation. The file you wrote is the file the browser runs.
Granular caching. Each module is cached independently. Deploy a change to one file and only that file is re-fetched. The rest of the application remains cached. In a bundled workflow, any change to any file invalidates the entire bundle.
Dependencies you understand. When you import a module from a URL or a local path, you know what it is. You chose it. You read it. There is no transitive dependency tree five levels deep, maintained by strangers whose names you have never encountered, executing code you have never read.
The 90% Argument
The honest assessment is this: for applications with five hundred or more modules, aggressive tree-shaking and code splitting remain valuable. The bundler earns its keep. Nobody disputes this.
The dishonest assessment is pretending that most projects are in this category.
They are not. The vast majority of web projects ship between ten and fifty modules. A marketing site, a dashboard, a content management front-end, an internal tool: these are not applications that require build-time dependency graph analysis. They are applications that require a script tag and a browser manufactured after 2017.
For ninety per cent of projects under fifty modules, the build pipeline is not solving complexity. The build pipeline is the complexity. The configuration file, the dependency tree, the plugin compatibility matrix, the CI minutes, the “works on my machine” debugging sessions: all of it exists to support a tool that the browser replaced eight years ago.
The Invoice
Let us be specific about what the build pipeline costs.
npm install: fetches packages you did not choose, maintained by people
you have not vetted, executing install scripts you have not read. The median
node_modules folder for a React project exceeds 200 MB.
webpack.config.js: the configuration file that nobody fully understands, inherited from a colleague who has since left, modified by Stack Overflow, maintained by prayer.
Babel: transpiles modern JavaScript to ES5 for browsers that corporate IT retired three years ago. In 2026, transpilation is predominantly an act of nostalgia.
CI minutes: the build runs on every push, consuming compute, generating artefacts, and adding latency to a feedback loop that could be instantaneous.
The native alternative: one script tag, zero configuration, granular caching, instant reload, and dependencies you chose deliberately. The browser has been ready since 2018. The protocol has been ready since 2015. The only thing not ready, apparently, is the industry.