Even nailing down the size of runtimes is unclear. You might go to bundlephobia.com but the size there can be misleading. With tree-shaking not all code is included. Bundlephobia also doesn't include sub-modules. Things like
There isn't only the size of the runtime but the size of the component code. Not all components are equal. Templates in each framework compile differently. Evan You, creator of Vue put together a comparison between Svelte and Vue which was pretty illuminating.
I'm the author of Solid, so be aware of that in terms of any potential bias I might show. I'm trying to keep things as equal as I can.
The test looks at the size of the library(vendor) bundle and the component code for TodoMVC. Every framework has a version and the requirements are well laid out so each is relatively the same.
I first looked at using only official demos, but Preact and React still use class components that are larger and not as representative of modern development. This did mean an increase in library size for Preact(3.81kb -> 4.39kb), which doesn't contain hooks as part of its main package but is definitely worthwhile for this test. In the end, I couldn't find a Hooks implementation I was happy with so I rolled my own implementation which I based off Solid's. You can find all the implementations here.
Vendor chunks are pulled from Vite which supports all tested frameworks. For component code I used Vue, Svelte, Solid's REPLs and Terser REPL to minify. For Preact and React I used rollup to generate the compiled code.
This process is much less rigorous than the benchmarks I typically do. Honestly coding style and available demo code put in a reasonable amount of variance. But I think it is still approximately in line.
First step is to get the size of the component and vendor code for each. TodoMVC is a pretty reasonable example as it involves basic state handling, conditional and loop rendering, forms, and even serialization to local storage. In so we get a much better idea of what the base size of each framework is than Bundlephobia.
|component size (brotli)||1.21kb||1.23kb||1.26kb||1.88kb||1.10kb|
|vendor size (brotli)||4.39kb||36.22kb||3.86kb||1.85kb||16.89kb|
Svelte's runtime really is small at 1.85kb. Preact core might be smaller than Solid, but with hooks in tow, the reactive framework ends up being the tinier one.
From this, it is easy to calculate the size of each framework at N number of TodoMVCs + vendor chunk.
While Svelte starts the charge in the lead, it is quickly overtaken by Solid, who passes the crown on to Preact. Preact is the smallest for a good chunk of the table before ultimately Vue is.
So putting the inflection points in a table:
This is the point each framework gets larger than the next. From 0-3 TodoMVCs, Svelte is the smallest. From 3 to 10 Solid is the smallest. 10-113 TodoMVCs Preact is. And more than 113 TodoMVC's Vue is.
Preact and Vue never intersect with React, and even for Solid that does it is only after about 1080 TodoMVC's. All in all this is pretty consistent with what we see in demo's and benchmarks. Svelte is always smallest for the Hello World's and TodoMVCs, Solid for the "Real World" demos and the types of simple sites people build on streams, and Preact for things on the larger side.
TodoMVC as a single component is on the larger side and typical implementations do it in 3-4 components so I wouldn't view these component numbers necessarily to be the number of components. But it is easy to see each framework has its sweet spot.
If this is a SPA that budget includes data fetching, state libraries, and router. It's not uncommon for that to be an additional 20 to 25kb JS with most frameworks. Reactive ones like Svelte, Solid, and Vue may have state management built-in but even then when you consider 3rd party utility libraries for formatting I'd say our framework and component code should be less than 100kb.
At that budget, just how many TodoMVCs does each framework allow for?
Well at 100kb React and Svelte are actually almost identical. And Vue, Preact, and Solid are right next to each other with almost 33% more budget available to them. But that's the upper end. At 40kb Preact and Solid can deliver pretty heft sites with a similar advantage over Vue and Svelte, at a range React isn't even really an option.
Alex's goal was 5 seconds TTI on a slower device and network. For some industries like eCommerce that target should be more like 3 seconds. 70kb - 25kb = ~45kb budget here. How can a larger library like React even compete?
But for the other's there is more room to play. A simple site might only 5-10 islands on a given page any option is good there. Even full SPAs for smaller libraries like Preact, Svelte, or Solid are well within a happy range.
Keep in mind this comparison is pretty rough and should be only seen as an estimate. I only regret not being able to put the time in to look at more libraries. Unsurprisingly a lot of TodoMVC examples are written MVC style which is unfair for this comparison or use stores like Redux. I wasn't prepared to write a bunch myself (Preact and React were enough). So this will have to stand.
Full source for the TodoMVC examples used in this article found here