I Built the Same App in 5 Frameworks: Next.js vs React vs Solid vs Svelte vs Vue
Same Cal.com clone. 5 frameworks. Here's what I learned about DX, architecture, and which one I'd pick for production in 2026.
I've been writing frontend code since before jQuery was cool. Over two decades of watching frameworks rise, peak, and sometimes quietly fade into legacy codebases. So when I wanted to stress-test my assumptions about the current framework landscape, I did the only reasonable thing: I built the exact same app five times.
The app is a Cal.com clone landing page -- hero section, feature grids, pricing cards, testimonials, navigation, footer. Complex enough to reveal real architectural differences. Simple enough to build in a weekend per framework.
Here's everything I learned.
The Setup
Every version renders the same pixel-perfect landing page. Same sections, same responsive behavior, same interactions. The only variable is the framework and its idioms.
| Framework | Files | Total Lines | Language | Styling Approach |
|---|---|---|---|---|
| Next.js | 13 component files | 1,112 | TypeScript + TSX | Tailwind CSS |
| React | 1 file (App.jsx) | 473 | JSX | CSS Modules |
| SolidJS | 1 file (App.jsx) | 525 | JSX | CSS |
| Svelte | 1 file (App.svelte) | 1,715 | Svelte 5 | Scoped styles |
| Vue | 1 file (App.vue) | 680 | SFC with script setup | Scoped styles |
The line count alone tells an interesting story. But it doesn't tell the whole story.
Next.js: The Enterprise Default
Next.js was the most structured build. TypeScript, Tailwind, App Router, component-per-file architecture -- the full production setup. Thirteen files for what the others achieved in one.
That's not a criticism. If I'm building something a team of five will maintain for two years, I want that separation. A PricingCard.tsx that does one thing. A Testimonials.tsx that owns its own data. The 1,112 lines are spread thin across small, focused components.
But for a landing page? It felt like driving a tank to the grocery store.
Verdict: Best for teams and production apps. Overkill for prototypes.
React: The Familiar Baseline
Plain React with Vite. No framework opinions, no file-based routing. Just JSX and CSS modules.
At 473 lines in a single App.jsx, this was the most concise JSX-based build. But "concise" is doing some heavy lifting here -- React requires the most ceremony around state. useState for every piece of reactive data, useEffect for side effects, manual dependency arrays that will bite you eventually.
React in 2026 is like English -- everyone speaks it, everyone has opinions about it, and the grammar is full of exceptions. It works. It's just not exciting anymore.
Verdict: Safe choice. You'll never get fired for picking React. You'll never get thrilled by it either.
SolidJS: The Reactivity Revelation
SolidJS was the surprise of this experiment. At 525 lines, it's only slightly larger than React -- but the developer experience is noticeably cleaner.
The difference is createSignal. Where React re-renders entire component trees and asks you to optimize with useMemo and useCallback, Solid tracks exactly which DOM nodes depend on which signals and updates only those. Fine-grained reactivity that actually makes sense.
Looks similar to React? It is -- intentionally. But under the hood, there are no virtual DOM diffs, no reconciliation passes. When isMenuOpen() changes, only the DOM elements that read it update. Nothing else re-executes.
Verdict: The cleanest mental model. If Solid had Next.js-level ecosystem and deployment story, I'd switch tomorrow.
Svelte: The Surprising Line Count Champion
Svelte 5 with runes. I expected this to be the most concise build. It wasn't -- at 1,715 lines, it's the largest single file by a wide margin.
Why? Scoped CSS. Every component's styles live inline in the same .svelte file. There's no external stylesheet to offload to. When you have a landing page with dozens of styled sections, those style blocks add up fast.
The actual logic is beautifully terse. $state and $derived are Svelte 5's runes -- they replaced the old $: reactive declarations. I like them better. They're explicit about what's reactive and what's computed, without the magic that sometimes tripped people up in Svelte 4.
But that 1,715-line single file is a real ergonomic problem. In a production app you'd split into components, which Svelte handles well. For this comparison though, it shows that Svelte's "all-in-one file" philosophy has a scaling ceiling.
Verdict: Best syntax for small-to-medium components. The scoped-styles-inline approach inflates file size on larger builds.
Vue: Batteries Included
Vue with Composition API and script setup. At 680 lines, it sits comfortably in the middle -- more than React, less than Svelte or Next.js.
Vue felt the most "batteries included" of the bunch. ref() and computed() are straightforward. onMounted() does what it says. The SFC format with script setup eliminates most boilerplate. Template syntax with v-for and v-if reads almost like HTML with superpowers.
The .value accessor is the one thing that trips up newcomers. You get used to it. The trade-off is that Vue's reactivity system is explicit -- you always know when you're reading or writing a reactive value.
Verdict: The most balanced DX. If I'm onboarding a junior dev, Vue is where I'd start.
The Full Comparison
| Aspect | Next.js | React | SolidJS | Svelte 5 | Vue 3 |
|---|---|---|---|---|---|
| Lines | 1,112 | 473 | 525 | 1,715 | 680 |
| Files | 13 | 1 | 1 | 1 | 1 |
| State Model | useState (React) | useState | createSignal | $state runes | ref() |
| Reactivity | VDOM diffing | VDOM diffing | Fine-grained | Compiled | Proxy-based |
| Learning Curve | Steep | Moderate | Low | Low | Low-Moderate |
| Ecosystem | Massive | Massive | Growing | Growing | Mature |
What Surprised Me
Svelte being the largest. I genuinely expected it to be the shortest. The runes syntax is incredibly concise for logic -- but when you factor in scoped styles, the numbers flip.
SolidJS being this good. The reactivity model is what React should have been. No dependency arrays, no stale closures, no useCallback ergonomic tax.
Next.js modularity isn't free. Thirteen files means thirteen imports, thirteen export declarations, thirteen decisions about prop interfaces.
React feeling... old. Not broken. Not bad. Just familiar in a way that makes you aware of every paper cut.
Which Would I Pick?
For a startup MVP: SolidJS. The DX is superb, the bundle size is tiny, and the reactivity model eliminates entire categories of bugs.
For a team project in production: Next.js. The structure scales. TypeScript is first-class. Vercel's deployment pipeline is unmatched.
For onboarding and teaching: Vue. The Composition API strikes the best balance between explicit and concise.
For pure joy of writing code: Svelte. The runes syntax is the closest any framework gets to "just write JavaScript."
For playing it safe: React. It's the lingua franca. Every hire knows it.
If you made me pick just one for everything? Today, in 2026, I'd pick SolidJS for greenfield and Next.js for anything that needs to survive contact with a team. The frameworks have converged enough on concepts -- signals, fine-grained reactivity, compiled output -- that the real differentiator is no longer features. It's how the code feels at 2 AM when you're debugging a production issue.
And on that metric, less magic wins every time.