โ All frameworksDev Time Performance
| Prod Deps | Dev Deps | Dup. Deps | node_modules | node_modules (prod) | Dep Install Size | Graph |
|---|
| 0 | 7 | 1 | 61.81MB | 0.02MB | 65.36MB | View |
| Metric | Avg | Min | Max |
|---|
| Install | 1.17s | 1.13s | 1.22s |
| Cold Build | 2.42s | 2.30s | 2.80s |
| Warm Build | 2.36s | 2.29s | 2.40s |
Build output size:1.29MB
Duplicate Dependencies
1 duplicate dependency detected across this starter's node_modules.
View 1 duplicate dependency
Runtime Performance
Client Side Rendered Tests
| Framework | First Paint | FCP | INP |
|---|
| SvelteKit | 112.2ms | 112.18ms | 9.38ms |
Methodology
- Each framework renders a table of 1000 rows with two UUID columns
- Measured using Lighthouse flow with Chromium via Puppeteer for accurate browser metrics
- First Paint and First Contentful Paint are measured on initial navigation
- Interaction to Next Paint is measured by clicking the first row's detail link
- Benchmarks run 5 times and results are averaged
- Next.js wraps the client-side rendered table in a
dynamic import with ssr: false to prevent build-time prerendering - TanStack Start, Nuxt, SvelteKit, and SolidStart disable SSR per-route
- React Router uses route-level
clientLoader functions with HydrateFallback so the client-rendered routes are not server-rendered - Astro uses client-only React islands for client-side rendered routes
- Client-side rendered tests use each framework's normal production build because SPA-only build modes are not supported consistently across the frameworks being compared
- Astro uses React for its client-side rendered test: the benchmark table and detail components are React islands rendered with
client:only="react", which prevents Astro from server-rendering those components and lets them render only in the browser. Astro's ClientRouter is not used for this CSR test because it enables client-side transitions and soft navigation behavior rather than client-only rendering.
Server Side Rendered Tests
| Framework | First Paint | FCP | INP |
|---|
| SvelteKit | 88.2ms | 88.3ms | 14.08ms |
Methodology
- Each framework renders a table of 1000 rows with two UUID columns
- Measured using Lighthouse flow with Chromium via Puppeteer for accurate browser metrics
- First Paint and First Contentful Paint are measured on initial navigation
- Interaction to Next Paint is measured by clicking the first row's detail link
- Benchmarks run 5 times and results are averaged
- The measured route is
/server-side-rendered, and detail navigation uses /server-side-rendered/:id.
Server Side Throughput Tests
| Framework | Ops/sec | Median Latency | Body Size | Duplication |
|---|
| Baseline HTML | 841 | 1.206ms | 96.83kb | 1x |
| SvelteKit | 424 | 2.284ms | 183.49kb | 2x |
Methodology
- Each framework renders the dedicated
/ssr-throughput route with a table of 1000 rows and UUID id/name columns - This route intentionally does not render the exact same table as the browser SSR and load tests: it omits detail links and framework link components so router, prefetch, and navigation metadata do not dominate the request-handler throughput measurement
- Mock HTTP requests bypass TCP overhead so this measures request-handler rendering throughput rather than full server throughput
- Data is loaded asynchronously to simulate real-world data fetching
- Duplication factor indicates how many times each UUID appears in the response (1x = optimal, 2x = includes hydration payload)
- Benchmarks run for 10 seconds using tinybench
- Frameworks are invoked through their production request handlers where possible. Web API handlers are called with
Request objects; Node.js handlers are called with mock IncomingMessage and ServerResponse objects. - Next.js renders the throughput table as a client component, matching the setup from PR #94, so the benchmark compares traditional server-rendered React + hydration work instead of making Next.js render every table row as React Server Components
- Inspired by eknkc/ssr-benchmark
Server Side Load Test
| Framework | Peak req/s | Peak Connections | P99 @ 25 | P99 @ 50 | P99 @ 100 | Total Req. |
|---|
| Baseline HTML | 1,629.8 | 50 | 20ms | 44ms | 107ms | 48,210 |
| SvelteKit | 497.4 | 25 | 78ms | 290ms | 2542ms | 15,662 |
Methodology
- Each framework serves the server-rendered table route over a real local HTTP server
- The measured route is
/server-side-rendered, using the same 1000-row UUID table as the SSR request throughput and browser rendering tests - Load is applied in staged connection counts, from 1 through 200 concurrent connections, with each stage running for approximately 5 seconds
- Peak requests/sec is the highest successful stage throughput observed during the staged run
- P90 and P99 latency are compared at the 25-, 50-, and 100-connection stages for every framework, so latency is measured under the same concurrency pressure
- Total requests cover the full staged load run, not only the peak stage