…and why “no-build, native ES modules” can quietly expand your attack surface if you’re not careful.

The seductive myth of a framework exodus

You’ve probably seen the headline:

“Developers are ditching frameworks for Vanilla JavaScript.”


It’s a compelling story. Everyone’s burnt out on React hooks discourse, upgrade churn, build tools, and megabyte bundles. Native browser APIs are better than ever. AI can scaffold code for you. And honestly, a clean index.html + a couple of <script type="module"> tags does feel refreshing after years of pipelines.


But there’s a difference between a cultural mood and an actual industry shift.


Yes, Vanilla JS is having a moment — especially in small projects, content-driven sites, and performance-obsessed setups. But the idea that frameworks are being abandoned misunderstands why they exist, how large teams work, and what actually happens when you throw unbundled ES modules into a real production environment.


This piece is a rebuttal to the “frameworks are over” narrative — and a warning: naive “no-build, native module” setups can introduce very real security risks if you don’t treat them with the same rigor you apply to your build chain.

Framework fatigue is real — but not a funeral

Framework fatigue isn’t imaginary. Developers are tired:


But fatigue doesn’t logically lead to “ditch frameworks.”

It leads to a different conclusion:


Frameworks arose to solve genuine problems:


These problems didn’t vanish in 2025 just because native APIs got nicer.

Native APIs are powerful — but they don’t replace architecture

Modern browsers are legitimately impressive now:


So, can you build rich interfaces with Vanilla JS + native APIs? Absolutely. For certain projects, it’s not just possible — it’s ideal.

But there’s a hard line between capability and architecture.


Native APIs don’t give you:


Web Components are a powerful primitive, but:


That’s exactly the space frameworks live in.

Performance isn’t just “less JavaScript = faster”

The “framework tax” is a real thing. Over-engineered SPAs for news articles, massive bundles for static marketing pages — that’s all fair criticism.


But the argument “Vanilla JS is always faster because it’s less JavaScript” is too shallow.

Modern frameworks have quietly evolved:


Meanwhile, hand-rolled Vanilla JS can easily become:


Performance is less about “framework vs no framework” and more about:


A minimal framework with strong defaults can outperform a sprawling DIY vanilla architecture any day.

AI doesn’t kill frameworks — it upgrades them

Another claim is that AI assistants make frameworks unnecessary because they can generate Vanilla JS quickly.

The reality: AI thrives on structure and convention.


Frameworks provide:


This means AI can:


Contrast that with a large Vanilla JS codebase where every team does things slightly differently. AI has less structure to lean on and more room for subtle misinterpretation.


AI doesn’t erase the need for frameworks; it reduces the cognitive cost of using them well.

The “no-build, native ES module” dream — and its security shadow

Now to the interesting part: unbundled native ES modules in production.

The vision is seductive:


This actually aligns nicely with the broader trend toward microfrontends and no-build architectures. But there’s a less discussed angle:

Every time you move responsibility from a controlled build pipeline to runtime resolution, you change your security story.


Let’s unpack some specific risks.

1. CDN sprawl and origin trust

Unbundled ES modules are often loaded from multiple origins:

<script type="module">import { something } from "https://cdn.example.com/some-lib/v1/index.js";
  import { helper } from "https://another-cdn.com/helpers.js";
</script>

Risks:


Framework setups usually centralize dependencies into a lockfile & build step. The shift to runtime resolution can make this much more diffuse.

2. Weak or absent integrity guarantees

Without a build step, teams often skip Subresource Integrity (SRI) and tight Content Security Policy (CSP) configurations.


Bundled builds, by contrast:


With native ES modules loaded directly from multiple origins, you must be deliberate about:

3. Dependency drift and silent changes

With unbundled ES modules:


Consequence: you lose deterministic builds.


Framework-driven bundlers are usually wired into CI:


If you’re going no-build with ES modules, you need equivalent rigor in a different place:

4. CSP, import maps, and attack surface creep

Import maps and ES modules give you new power — and new footguns.

An import map like:

<script type="importmap">
{
  "imports": {
    "lib": "https://cdn.example.com/lib/v1/index.js"
  }
}
</script>


If an attacker finds any injection vector that lets them modify this block (or inject a new one), they can:


CSP can help, but:


No-build architectures demand more disciplined CSP than many teams currently practice, not less.

5. Observability blind spots

When everything goes through a build pipeline:


With unbundled ES modules:


Unless you intentionally:

…you’ll likely lose visibility into what’s actually executing in the client.

Vanilla JS vs frameworks is the wrong fight

Stepping back, the real story isn’t:

Frameworks bad, Vanilla JS good.


It’s more:

We abused frameworks where they weren’t needed,
frameworks grew heavy in response to real complexity,
the platform has caught up,
and now we have more options than ever.


Vanilla JS (plus modern browser APIs) is fantastic for:


Frameworks remain essential for:


And the security story is this:


Without that discipline, your “no-build, framework-free” setup can quietly become more fragile and more exposed than the “bloated” framework app you were trying to escape.

The real reset: intentional choices, not pendulum swings

The framework hangover is actually a wake-up call, but not the one the slogans suggest.

It’s not:

Rip out your framework and go raw Vanilla JS.


It’s closer to:

Use frameworks where their structure, tooling, and ecosystem bring real value.
Use the platform directly where it’s enough.
And wherever you land — with or without a build step — treat security, observability and maintainability as first-class concerns.


In 2026, writing Vanilla JS doesn’t mean you’re going backwards.

And using a framework doesn’t mean you’re stuck in the past.

Progress isn’t about picking a side in “Vanilla vs Frameworks.”

It’s about mastering both and being honest about the tradeoffs of each, including the security ones.