Back to Blog
Engineering March 13, 2026 · 10 min read

Vanilla JS Is the Assembly Language of the Browser (And That's Why We Use It)

GM

Gonzalo Monzón

Founder & Lead Architect

In February 2023, Alex Russell — who spent over a decade on the Google Chrome team — published "The Market for Lemons", a devastating critique of the JavaScript framework industry. His thesis: for a decade, "complexity merchants" sold heavy frameworks as the future of the web, while the resulting products were slower, more fragile, and worse for users. His conclusion: "We need to move our attention back to the folks who never gave up on semantic markup, CSS, and progressive enhancement." We are those folks. And we have numbers to prove it.

The Bloat Is Real (and Measurable)

In early 2024, Nikita Tonsky published "JavaScript Bloat in 2024", a methodical audit of how much JavaScript popular sites ship. The results are staggering:

SiteWhat It DoesJavaScript Shipped
Tonsky's blogStatic content0.004 MB
WikipediaStatic content + search0.2 MB
GmailEmail client20 MB
SlackChat55 MB
JiraTask management50 MB
LinkedInSocial + messaging31 MB
NotionDocument editing16 MB
Vercel landingStatic landing page6 MB

Slack ships 55 MB of JavaScript — the size of the original Quake 1 — for a chat app. Meanwhile, Tonsky's blog delivers the same core value (showing text to humans) with 0.004 MB. That's a 13,750x difference in code for fundamentally similar output: text on a screen.

As Tonsky put it: "Call me old-fashioned, but I firmly believe content should outweigh code size. If you are writing a blog post for 10K characters, you don't need 1000× more JavaScript to render it."

The Assembly Analogy

Vanilla JavaScript and pure CSS are to the browser what assembly language is to the CPU. They are the native instruction set. Everything else — React, Vue, Svelte, Tailwind, Sass — compiles down to them eventually. Every useState becomes a closure. Every className="flex items-center" becomes a CSS rule. Every JSX expression becomes a document.createElement call.

When you understand the low-level primitives, you gain three superpowers:

  • You know what's actually happening. When something breaks, you don't debug the framework — you debug the browser. DevTools speaks vanilla JS and CSS, not React or Vue
  • You can evaluate frameworks honestly. You know what they're abstracting, what they cost, and whether that cost is justified for your use case
  • You can build without them. When a framework adds overhead that doesn't serve the user, you have the option to simply... not use it

This doesn't mean frameworks are bad. It means knowing when not to use one is the skill that separates engineers from framework operators.

The Market for Lemons: A Decade Lost

Alex Russell's critique is worth reading in full, but the key argument is economic. When sellers have more information than buyers, low-quality products dominate the market — Akerlof's "lemons" theory. Applied to frontend:

"Partisans for slow, complex frameworks have successfully marketed lemons as the hot new thing, despite the pervasive failures in their wake, crowding out higher-quality options in the process."

Alex Russell, The Market for Lemons (2023)

The frameworks were born at Facebook and Google — companies with dedicated performance teams, ship gates, latency budgets, and hundreds of engineers to manage complexity. When transplanted to a typical team of 3-10 developers, these tools became expensive duds: slow to load, fragile to maintain, and requiring an entire ecosystem of abstractions (SSR, code splitting, hydration, streaming) to mitigate problems they themselves created.

Jeremy Keith, one of the most respected voices in web standards, put it bluntly in November 2023: "At this point React is legacy technology, like Angular. Lots of people are still using it, but nobody can quite remember why."

The Great Gaslighting

Jared White of The Spicy Web captured what many of us felt for years:

"We were told writing apps with an HTML-first, SSR-first, progressively enhanced mindset was outdated and bad for users. That was a lie. We were told writing apps completely using frontend JavaScript would make our lives easier. That also was a lie."

His core point is devastating: "JavaScript is not required to build a simple web site. HTML, CSS, and JavaScript. Not JavaScript, JavaScript, and JavaScript."

The web is polyglot by design. HTTP doesn't care what language generates the HTML. The browser doesn't care what tool wrote the CSS. The user doesn't care about your DX — they care about speed, reliability, and whether the damn button works.

Web Components Will Outlive Your Framework

Jake Lazaroff wrote one of the most important posts of 2023 about this theme. His argument: if you want your work to last, build on web standards, not framework APIs.

"I've been building on the web for almost 20 years. That's long enough to witness the birth, rise and fall of jQuery. Backbone burst onto the scene and was quickly replaced with AngularJS, which was replaced with React, which has been around for only half that time and has still gone through like five different ways to write components."

The original Space Jam website from 1996 still renders perfectly in modern browsers. The first website ever created — closer to the formation of the Beatles than to today — still works. Meanwhile, React projects from 2018 often won't compile without major dependency surgery.

Standards last. Frameworks don't. Choose accordingly.

The htmx Case Study: 67% Less Code, 50% Faster

Theory is fine, but what about real-world results? At DjangoCon 2022, Contexte presented their port from React to htmx. The numbers speak for themselves:

MetricReactAfter (htmx)Change
Codebase size21,500 LOC7,200 LOC-67%
JS dependencies2559-96%
Build time40 seconds5 seconds-88%
Time to interactive2-6 seconds1-2 seconds-50-60%
Memory usage75 MB45 MB-46%

But the most revealing change was organizational: the entire team became full-stack developers. With React, there was a hard split between frontend and backend. Without it, every developer could own a feature end-to-end. Less coordination, faster shipping, happier engineers.

Our Approach: Know the Low Level, Choose the Right Level

We're not framework haters. We're not building everything in vanilla JS out of dogma. We're engineers who understand the low-level primitives and choose the right abstraction for each job. Here's how that plays out across our stack:

Pure Vanilla JS + CSS (zero dependencies)

  • cookie-consent.js — Our entire cookie consent system: IIFE, self-contained CSS injection, localStorage, bilingual UI, analytics gating. 4KB total, zero dependencies. A React equivalent with a UI library would be 50-200KB minimum
  • Perspectiva Studio — ~15 modules (audio, video, chat, embeddings, publications, model management) in pure vanilla JS. No build step. Open index.html in a browser and it works. Has worked for years without a single dependency update
  • Client landing pages (Vall, NutriNen, etc.) — Static HTML, pure CSS, Alpine.js for sprinkles of interactivity. Load in under 1 second on 3G

Astro (SSG — static site generation)

  • cadenceslab.com — This very site. Astro generates static HTML at build time. The blog you're reading is a pre-rendered HTML file. Zero JavaScript shipped to the client for content pages. Astro earns its place because it does one thing superbly: turn components into static HTML and get out of the way
  • GoViajes, GoStorm — Travel and event platforms where the content is mostly static but the data model benefits from Astro's collections and i18n routing

React (interactive islands)

  • Cadences platform — The main product is a complex interactive app: real-time project management, AI chat, voice integration, workflow builders, data explorers. React earns its place here because the UI is genuinely stateful, interactive, and complex
  • Blog interactive components — When a blog post needs a live demo or interactive widget, we use React as an Astro island: it hydrates only when visible, ships JS only for that component, and the surrounding page remains static HTML

The decision tree is simple:

Is it static content? → HTML + CSS. Done.
Needs a sprinkle of interactivity? → Vanilla JS or Alpine.js
Needs SSG with routing/i18n? → Astro
Genuinely complex interactive UI? → React (as island or SPA)
Could it be simpler? → Go back to step 1

What We Actually Ship (By the Numbers)

ProductTechJS Shipped to ClientWhy This Choice
cadenceslab.comAstro + islands~15KB (Alpine + consent)Content site, needs zero client JS for content
Cookie consentVanilla JS4KBSelf-contained, no dependencies to maintain
Perspectiva StudioVanilla JS~80KB (15 modules)No build step, works forever
Client landingsHTML + CSS + Alpine~12KBMaximum performance, minimum complexity
Cadences appReact~350KBComplex interactive UI justifies the cost

Compare our content site (15KB) to Vercel's landing page (6MB). That's a 400x difference. Our entire cookie consent system is smaller than the average React useState tutorial page.

Pure CSS: The Forgotten Superpower

The same principle applies to CSS. While the industry was busy inventing CSS-in-JS, CSS Modules, Styled Components, Emotion, and seventeen flavors of utility classes, the browser was quietly shipping features that make most of those tools unnecessary:

  • CSS Custom Properties — Native variables with cascade inheritance. No build step needed
  • CSS Grid + Flexbox — Layout solved natively. No Bootstrap grid, no flexbox utilities
  • :has() selector — The "parent selector" we waited 20 years for. Now you can style based on children without a single line of JS
  • @container queries — Component-level responsive design, natively
  • @layer — Native cascade management. No more !important wars
  • Nesting — Native CSS nesting, no Sass required
  • color-mix(), oklch() — Advanced color manipulation without preprocessors

Our client pages use pure CSS with custom properties for theming. Each brand (Vall Inmobiliaria, NutriNen, GoViajes) gets its own CSS file with a custom property palette — no Tailwind config, no build step, no PostCSS. Change --brand-primary and the entire site rebrands. It's CSS doing what CSS was designed to do.

The Longevity Argument

Jake Lazaroff's point about longevity deserves repetition. Our Perspectiva Studio modules — written in vanilla JS years ago — still work perfectly today. No npm audit alerts. No breaking changes from dependency updates. No "this project uses React 16 and needs to be migrated to 18." Open the HTML file, it works.

TypeScript is wonderful, but even it has breaking changes in every release. As Lazaroff noted: "the last 15 versions of TypeScript have had breaking changes." For long-lived code that you don't plan to actively maintain, vanilla JS is the safest bet. It's the one technology guaranteed not to break, because the browser makers have committed to never breaking the web.

The first website, built in 1991, still works. Can you say the same about your React app from 2019?

Key Takeaways

1. Vanilla JS and pure CSS are the browser's native instruction set. Everything else compiles to them. Understanding them deeply isn't "old school" — it's the foundation that lets you evaluate and choose (or refuse) every other tool. The engineers who know the low level always have the advantage.

2. The framework tax is real and measurable. 55MB of JS for a chat app. 20MB for an email client. 6MB for a landing page. The "complexity merchants" sold DX improvements that degraded UX. As Alex Russell documented, the industry lost a decade to the market for lemons.

3. We're not anti-framework — we're anti-default-framework. React powers our Cadences platform because complex interactive UIs genuinely benefit from it. Astro generates this blog because static site generation is genuinely useful. But cookie consent doesn't need React. A landing page doesn't need Next.js. The right tool for the job is sometimes no tool at all.

4. Web standards outlive everything. jQuery came and went. AngularJS came and went. React's had five different component patterns in 10 years. HTML, CSS, and vanilla JS from 1996 still work perfectly. Build on the substrate, not on the abstraction layer that'll be deprecated next year.

5. The best DX is invisible infrastructure. Our cookie-consent.js has zero dependencies, zero build steps, and hasn't needed an update since it was written. Perspectiva Studio's 15 modules work by opening an HTML file. That's not tech debt — that's tech freedom. The less your code depends on, the less it can break.

Tags

JavaScript CSS Web Standards Performance Architecture Vanilla JS Web Components

About the Author

Gonzalo Monzón

Gonzalo Monzón

Founder & Lead Architect

Gonzalo Monzón is a Senior Solutions Architect & AI Engineer with over 26 years building mission-critical systems in Healthcare, Industrial Automation, and enterprise AI. Founder of Cadences Lab, he specializes in bridging legacy infrastructure with cutting-edge technology.

Stay in the loop

Get notified when we publish new articles about AI automation, use cases, and practical guides.