Framework discussions usually focus on DX, ecosystem, and runtime performance. But users experience something earlier than all of that: download, decompress, parse, then execute.
That is why I built this benchmark: to make framework bundle-size tradeoffs visible under the same feature scope and the same reporting rules.
What I benchmarked
I implemented the same TodoMVC feature set across multiple frameworks, then generated one unified report.
The report compares:
- raw size
- minified size
- minified + gzip size
It also breaks totals down by:
- runtime
- template
- script
- style
Fairness constraints
To reduce noise from implementation differences:
- all frameworks implement the same TodoMVC behavior
- template/script/style outputs are extracted and compared
- styles are scoped in all implementations (TSX-based implementations use CSS Modules)
- the UI does not select style by default, but style is still included in stats
Why style is not selected by default in the chart controls:
style usually has limited optimization room in this setup, and differences are often tiny and mostly caused by framework-added scoping metadata rather than major architecture differences.
Mainstream group: React, Angular, Vue (Vue 3)
At 1 component (minified):
- Angular: ~201.69 KB
- React: ~189.44 KB
- Vue 3: ~65.64 KB
The key reason is runtime cost. In the same report view:
- Angular runtime: ~195.39 KB
- React runtime: ~185.66 KB
- Vue 3 runtime: ~61.83 KB
As component count grows, the gap expands. Angular rises fastest, React also stays high, and Vue 3 remains lower overall in this group in this benchmark.
Fine-grained group: Solid, Vue Vapor, Svelte 5, QingKuai
The ecosystem trend is clear: less generic virtual-DOM diffing, more dependency-precise updates (fine-grained reactivity).
But in practice, frameworks in the same direction can still differ a lot.
At 1 component (minified):
- Solid: ~19.04 KB
- QingKuai: ~25.42 KB
- Svelte 5: ~39.25 KB
- Vue Vapor: ~47.27 KB
If you only look at the starting point, Solid is smallest in this group.
But if you look at growth curves, the story changes:
- QingKuai grows more smoothly and ends up lowest at high component counts in this run
- Solid starts smallest but grows faster
- Svelte 5 and Vue Vapor stay above QingKuai in higher component-count ranges, while Vue Vapor remains below Solid and Svelte 5 at larger scales
So the useful takeaway is not just “fine-grained is better.”
It is: how the runtime is organized and how costs scale with component count matters more than a single low starting number.
Why Svelte 4 deserves a separate note
Svelte 4 has a very attractive small-app story.
At 1 component (minified), it is ~11.08 KB in this benchmark, with runtime at ~0.71 KB.
But at larger scales, its curve becomes much steeper than peers in this comparison.
This suggests a common risk pattern for larger apps:
- very low centralized runtime cost
- more repeated implementation fragments embedded in component output
- total size grows quickly as component count increases
Practical guidance from this dataset:
- for very small apps (for example, under ~10 components), Svelte 4 can still be a reasonable choice
- for larger applications, evaluate growth slope early, not just the smallest demo number
The metric that matters: starting point + slope
This benchmark reinforced four points for me:
- Bundle size should be a first-class framework selection metric.
- “No virtual DOM + fine-grained” is an important direction, but implementations in that direction can still differ significantly.
- The smallest 1-component result is not enough.
- For medium/large apps, growth slope is often more important than the best single-point minimum.
Reproduce locally
git clone https://github.com/mlgq/frontend-framework-bundle-size.git
cd frontend-framework-bundle-size
pnpm install
pnpm run report
Links
If you find an unfair implementation detail or have better optimizations, critiques and PRs are welcome.






Top comments (0)