A few years ago, I wrote about the new trend in web development: keeping it simple. Back then, it felt like a counter-culture movement....
A few years ago, I wrote about the new trend in web development: keeping it simple. Back then, it felt like a counter-culture movement. Today? It's closer to becoming mainstream. And the reason is simple: the web platform caught up.
The tools we adopted 10 years ago on front-end - bundlers, minifiers, package managers for browser code - they solved real problems. Problems that existed in 2015. But the web has changed dramatically since then, and a lot of developers haven't noticed. I would argue most developers are still using the "modern" stack out of habit, not necessity.
Let me show you what's changed. No opinions here - just facts about web technology that might make you reconsider your build process.
Here's the thing that blows my mind: the entire premise of bundling is based on HTTP/1.1 limitations. And HTTP/1.1 is... old.
In HTTP/1.1, every file you loaded meant a new TCP connection. Handshake. Negotiation. Overhead. Loading 50 separate JavaScript files was genuinely slow. So we bundled everything into one big file. Smart!
But HTTP/2 came out in 2015. It multiplexes multiple requests over a single connection. Fifty small files? Basically the same performance as one bundled file. Sometimes faster, because browsers can cache individual files and only re-download what changed.
HTTP/3 (2022) made this even better with QUIC - no head-of-line blocking, faster multiplexing.
The math changed. The advice didn't.
Most servers have supported HTTP/2 for years now. Cloudflare, nginx, Apache, most CDNs - it's the default. Yet devs are still bundling like it's 2014.
(Fair caveat: bundling does still help with compression - one large file compresses better than many small ones. But for most projects with a handful of libraries, the difference is negligible - you are not planning to load 200 files on one page, right... Right?!?!)
This one is huge and most developers I talk to don't even know it exists.
Import Maps are a W3C standard. They're supported in Chrome, Edge, Firefox, and Safari (since 2023). Here's what they do:
<script type="importmap">
{
"imports": {
"lodash": "https://esm.sh/[email protected]",
"axios": "https://esm.sh/[email protected]"
}
}
</script>
<script type="module">
import _ from 'lodash';
import axios from 'axios';
// Just works. No npm. No bundler. No build step.
</script>
That's it. You map package names to URLs, and the browser handles module resolution natively. You can point to CDNs, or to files on your own server. The browser doesn't care.
This is the same philosophy Deno uses - and Deno was created by Ryan Dahl, the guy who made Node.js, partly because he had regrets about how complex things got.
Import maps aren't experimental. They're in the browser spec. They work today.
(One thing to keep in mind: if you use CDN URLs, you're trusting that CDN to stay up. For production apps, consider self-hosting your dependencies or using a fallback strategy. But that's a solvable problem - not a reason to pull in the entire npm/bundler toolchain.)
Remember why we needed Webpack in the first place? Browsers didn't understand import and export. You had to transpile everything.
That changed in 2018. All major browsers now support ES Modules natively:
<script type="module">
import { formatDate } from './utils.js';
console.log(formatDate(new Date()));
</script>
No transpilation. No bundler. It just works.
You can even use <link rel="modulepreload"> to tell the browser which modules to fetch early:
<link rel="modulepreload" href="/js/utils.js">
<link rel="modulepreload" href="/js/app.js">
The browser handles the dependency graph. That was supposed to be a bundler benefit. Now it's a browser feature.
"But I need to minify for performance!"
Do you, though? Let's look at actual numbers.
Minification typically saves 20-30% on file size. It removes whitespace, shortens variable names, etc.
Gzip compression saves 70-90% on text files. Brotli is even better.
Here's Bootstrap CSS as an example:
So minification on top of gzipping saves you... 2KB. On a 227KB file.
Every modern web server gzips by default. Nginx does it. Apache does it. Cloudflare does it. Your hosting probably already has it enabled.
Is the complexity of a minification step worth 2KB? For most projects, I'd argue no. The benefit is marginal, the tooling overhead is real.
Sure, for truly massive applications, every byte counts. But for your admin panel or marketing site? Come on.
Now, tree-shaking is a different story. Bundlers can remove unused code from libraries - and that can be significant. If you import one function from lodash, a bundler can exclude the other 99%. That's genuinely useful. But it also only matters if you're using large libraries and only need small parts of them. For many projects, loading the full (gzipped) library is fine.
This isn't just me being grumpy about complexity. Look at what the frameworks themselves are doing:
The SPA model that required complex build tooling is being actively questioned by the people who built it. React Server Components exist because even the React team realized we went too far with client-side rendering.
If the framework authors are saying "maybe we don't need all this JavaScript"... maybe we don't need all this JavaScript.
(To be fair: these frameworks still use bundlers internally. But the point is - they're optimizing for less client-side JS, which means simpler apps might not need the complexity at all.)
I won't go deep on this (that's a separate article), but quickly: a lot of what we needed Sass/Less for is now native CSS.
CSS Variables:
:root {
--primary: #3490dc;
}
.button {
background: var(--primary);
}
CSS Nesting (native since 2023!):
.card {
background: white;
&:hover {
background: #f5f5f5;
}
.title {
font-size: 1.5rem;
}
}
Container Queries, @scope, :has() selector - all native now. The main reasons people used CSS preprocessors are disappearing.
Look, I'm not saying bundlers are useless. If you're building:
...then yes, a bundler might make sense.
But be honest with yourself. Is that what you're building?
Most web projects are:
For those, the "modern" JavaScript toolchain is often solving problems you don't have, using solutions from 2015 for a web platform that's evolved dramatically since then.
Here's what a simpler stack looks like in 2026:
import statements without a bundlerNo node_modules. No package.json for browser code. No webpack/vite/rollup/esbuild config files. No build step that can break.
Just HTML, CSS, and JavaScript. The way the web was designed to work. But now with HTTP/2, Import Maps, and native ES Modules making it actually practical.
I've been building web apps for 15+ years. I've seen trends come and go. And one thing I've learned is: the web platform usually catches up. Not particularly fast - but it does!
We invented bundlers because browsers were limited. Now browsers aren't limited - but we're still bundling. We invented CSS preprocessors because CSS was limited. Now CSS has variables and nesting - but we're still preprocessing. We invented SPAs because server-rendering was slow. Now server-rendering is fast and everyone's moving back to it.
The tools we adopted were solutions to problems. The problems changed. Maybe it's time to reconsider the solutions.
I'm not saying everyone should ditch their bundler tomorrow. But next time you start a project, maybe ask yourself: do I actually need this? Or am I just using it because... that's what everyone does?
I would argue a lot of times, the simplest approach is also the best one.
Cheers! 🍻
Subscribe to our "Article Digest". We'll send you a list of the new articles, every week, month or quarter - your choice.
What do you think about this?
Wondering what our community has been up to?