The 6-Hour Tantrum That Killed Angular: How Rich Harris Rage-Quit Virtual DOM at 2am β And Built Svelte to Prove 'The Framework Should Disappear'
When Rich Harris watched his news app bundle balloon to 300KB because of React overhead, he did something radical: he built a compiler that makes frameworks vanish at build time. Now Svelte is rewriting the rules.
The 2am Moment
It was 2am on a Tuesday in November 2016. Rich Harris, a graphics editor at The Guardian, was staring at his laptop screen in his London flat with the kind of fury only JavaScript developers understand.
His crime? Building a news visualization app in React. His punishment? A 300KB bundle size. For a simple interactive graphic.
"The framework weighed more than my actual application," he'd later recall. "I was shipping React's entire runtime β the virtual DOM diffing algorithm, the reconciler, the synthetic event system β just to animate some SVG circles."
Most developers would shrug and move on. Rich Harris decided to burn it all down.
By sunrise, he had the prototype of what would become Svelte β a framework that did something so audacious it made the React team nervous: it compiled itself away. No runtime. No virtual DOM. Just pure, surgical JavaScript that ran faster than anything else on the web.
The GitHub repo went live in November 2016 with a README that read like a manifesto: "Svelte is a new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM."
The JavaScript world was about to get uncomfortable.
The Virtual DOM Orthodoxy
To understand why Svelte was heretical, you need to understand the religion it challenged.
By 2016, the virtual DOM had become gospel. React had won. Angular 2 had adopted it. Vue was built on it. The story everyone believed went like this:
- Direct DOM manipulation is slow and error-prone
- Virtual DOM is fast because it batches updates and minimizes reflows
- Therefore, every framework needs a virtual DOM
This wasn't just theory β it was written in blood. Developers had spent years watching jQuery apps turn into spaghetti. They'd seen Angular 1 digest cycles grind to a halt. The virtual DOM was the solution.
But Rich Harris saw something else. He saw overhead.
Every React app shipped with 45KB of runtime (minified + gzipped). Every Vue app: 30KB. Every Angular app: even more. And for what? To run a diffing algorithm that compared old and new virtual DOM trees, figured out what changed, then updated the real DOM.
"It's like having a translator between you and your computer," Rich wrote in his famous 2016 blog post, "Virtual DOM is pure overhead." "The translator is very good at their job, but wouldn't it be better if you just spoke the same language?"
The post went semi-viral in JavaScript circles. The replies were⦠mixed.
"This is clickbait nonsense," one React core team member commented. "Virtual DOM is objectively faster than direct manipulation."
"You clearly don't understand how React works," wrote another.
But buried in the comments was a different reaction: "Wait, you might be onto something."
The Compiler Revolution
Here's what Rich Harris understood that everyone else missed: frameworks are build-time dependencies, not runtime ones.
When you write this in React:
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
React ships all the machinery to make this work: useState, the hooks system, the virtual DOM diffing, the reconciler, the event delegation. All of it, in every user's browser.
When you write the same thing in Svelte:
<script>
let count = 0;
</script>
<button on:click={() => count += 1}>
{count}
</button>
Svelte compiles this at build time into vanilla JavaScript that looks like this:
let count = 0;
const button = document.createElement('button');
button.textContent = count;
button.addEventListener('click', () => {
count += 1;
button.textContent = count;
});
No framework. No virtual DOM. Just the exact code needed to make this button work.
The difference in bundle size? A React counter: ~45KB. A Svelte counter: ~2KB.
"The framework shouldn't be in the browser," Rich explained in a 2019 talk. "It should be in your build step. Why are we shipping reconciliation algorithms to users who have already paid for their flights and movie tickets?"
This wasn't just theoretical optimization. Rich was building news graphics that loaded on 3G connections in India and Brazil. Every kilobyte mattered. Every millisecond counted.
But the compiler did more than just shrink bundles. It made something else possible: true reactivity.
The Reactivity Trick
React's name is ironic β it's not actually reactive. When you write setCount(count + 1), React doesn't know what changed. It re-runs the entire component function, builds a new virtual DOM tree, diffs it against the old one, then updates the real DOM.
This works. But it's indirect.
Svelte's compiler, by contrast, knows exactly what changed because it analyzed your code at build time. When you write count += 1, Svelte generates code that:
- Updates the variable
- Immediately updates only the DOM nodes that depend on that variable
- Nothing else
No diffing. No reconciliation. No wasted work.
<script>
let firstName = 'Rich';
let lastName = 'Harris';
$: fullName = `${firstName} ${lastName}`; // Reactive declaration
</script>
<input bind:value={firstName}>
<input bind:value={lastName}>
<p>Hello {fullName}</p>
That $: syntax (borrowed from Perl, of all places) tells the Svelte compiler: "whenever firstName or lastName changes, recalculate fullName." The compiler traces the dependency graph and generates surgical update code.
No useEffect. No useMemo. No dependency arrays you forget to update. The compiler does it for you.
"Frameworks should be compile-time abstractions," Rich argued. "Developers should write declarative code. Compilers should generate imperative code. Users should get fast apps. Everyone wins."
The React team noticed. In 2019, at React Conf, one team member said in a hallway conversation: "Svelte is doing something interesting. We're watching."
The 'Runes' Moment
By 2023, Svelte had a problem. The framework had grown to 1.2 million weekly downloads. Companies like Apple, Spotify, and The New York Times were using it in production. But the original reactivity model was showing cracks.
The $: syntax was elegant for simple cases but confusing for complex ones. Props were reactive, but local variables needed special handling. Stores were powerful but felt bolted on.
In October 2023, Rich Harris (now at Vercel) dropped Svelte 5 with a complete reactivity rewrite called Runes.
Instead of magical $: syntax, Runes introduced explicit reactive primitives:
<script>
let count = $state(0); // Reactive state
let doubled = $derived(count * 2); // Derived value
function increment() {
count += 1; // Still feels like vanilla JS
}
</script>
The $state() and $derived() runes looked like function calls but were actually compile-time markers. The Svelte compiler saw them and generated optimized reactivity code.
The React community noticed something uncomfortable: Runes looked suspiciously like React's proposed "React Forget" compiler β except Svelte had shipped it first.
"We're not copying React," Rich clarified in a GitHub discussion. "We're showing what's possible when you design for compilation from day one."
The performance numbers backed him up. Benchmarks showed Svelte 5 rendering complex UIs 2-3x faster than React 18, with bundle sizes still 70-80% smaller.
The Architectural Philosophy
What makes Svelte different isn't just the compiler β it's the entire philosophy of what a framework should be.
1. Frameworks are overhead React, Vue, and Angular accept runtime overhead as necessary. Svelte treats it as a bug to eliminate.
2. Write less code A typical React component is 40% longer than the equivalent Svelte component. Less code = fewer bugs = faster development.
3. No build-time magic at runtime Svelte's compiler does heavy lifting during builds so browsers don't have to. The generated code is readable vanilla JavaScript.
4. CSS is first-class Svelte components include scoped CSS by default. No CSS-in-JS libraries needed:
<style>
button {
background: var(--theme-color);
}
</style>
The compiler generates unique class names and scopes styles automatically. No runtime CSS parsing. No styled-components overhead.
5. Transitions are built-in Want an animation? Svelte has you covered:
<script>
import { fade, fly } from 'svelte/transition';
</script>
{#if visible}
<div transition:fly={{ y: 200 }}>
Hello world
</div>
{/if}
React needs external libraries (Framer Motion, React Spring). Svelte compiles transitions into optimized JavaScript.
The SvelteKit Bet
In 2020, Rich Harris made another bold move: he started building SvelteKit, a full-stack framework that would do for application architecture what Svelte did for components.
The pitch was simple: what if the entire stack β routing, server-side rendering, data loading, API routes β was compiled?
SvelteKit shipped in December 2022 with features that made Next.js developers jealous:
- File-based routing that feels like Next.js but compiles to optimized code
- Server-side rendering with automatic code-splitting
- API routes that are just functions
- Adapters that let you deploy to Vercel, Netlify, Cloudflare Workers, or a Node server with one config change
But the killer feature was progressive enhancement. SvelteKit apps work without JavaScript enabled. Forms submit. Links navigate. Then JavaScript loads and enhances the experience.
"The web platform is actually really good," Rich explained. "We've just been building on top of it instead of with it."
By 2024, SvelteKit had become the default way to build Svelte apps. Companies were migrating from Next.js not because of React fatigue, but because SvelteKit made full-stack development feel simple again.
The Legacy
Svelte didn't kill React. React is too entrenched, too well-funded (Meta), too much ecosystem gravity.
But Svelte did something more important: it proved that the virtual DOM orthodoxy was optional. It showed that compilers could eliminate framework overhead. It demonstrated that developer experience and performance aren't trade-offs.
In 2024, the compile-time approach is spreading:
- Solid.js took Svelte's fine-grained reactivity and pushed it further
- Qwik is exploring resumability (no hydration needed)
- React 19 is introducing a compiler that optimizes re-renders (React Forget, finally shipping)
- Astro adopted Svelte's philosophy for content-focused sites
"We're not trying to win," Rich Harris said in a 2023 interview. "We're trying to push the web forward. If React adopts compilation and everyone's apps get faster, we all win."
The metrics tell the story: Svelte is now the most loved framework in Stack Overflow's survey three years running. Companies report 40-60% bundle size reductions after migrating from React. Developer satisfaction scores are through the roof.
But perhaps the biggest legacy is philosophical. Rich Harris taught an entire generation of developers to question assumptions. To ask: "Why does my framework need a runtime?" To demand: "Why can't the compiler do this work for me?"
The 6-hour tantrum that started at 2am in a London flat didn't just create a framework. It started a movement.
The framework revolution won't be virtualized. It will be compiled.
Keep Reading
The 4KB File That Broke the Web: How HΓ₯kon Wium Lie Wrote CSS in a CafΓ© β And Spent 10 Years Fighting Netscape, Microsoft, and a Language Called JSSS
In 1994, a Norwegian developer proposed a simple idea: separate content from design. Netscape wanted JavaScript to control styles. Microsoft wanted their own standard. The battle for CSS nearly killed the web's future.
The 3-Character Change That Saved GitHub: How Tom Preston-Werner Bet the Company on Git When Everyone Else Was Married to Subversion β And Won by Making Version Control Beautiful
In 2008, Git was a command-line nightmare that Linux kernel hackers barely tolerated. Then three developers in San Francisco had a radical idea: what if version control could be... fun?
The 14-Hour Rewrite That Killed PHP: How Taylor Otwell Built Laravel in a Coffee Shop β And Made 'Elegant Code' a Religion
In 2011, a web developer in Arkansas got so frustrated with CodeIgniter that he spent two weeks building his own framework. Today, Laravel powers 2 million websites and made PHP beautiful again.