โ All frameworks Dev Time Performance
| Prod Deps | Dev Deps | Dup. Deps | node_modules | node_modules (prod) | Dep Install Size | Graph |
| 3 | 6 | 12 | 560.04MB | 436.00MB | 506.22MB | View |
| Metric | Avg | Min | Max |
| Install | 3.14s | 2.96s | 3.78s |
| Cold Build | 5.29s | 5.04s | 5.38s |
| Warm Build | 5.25s | 5.04s | 5.44s |
Build output size: 6.22MB
Unnecessary Core-JS Polyfills
302
core-js
polyfill modules are bundled but
already natively supported by the
last 2 major versions of Chrome, Firefox, Safari, and Edge
โ code users download even though their browser already supports it
natively.
The containing chunk is approximately 110.0 KB (chunk size, not isolated
core-js bytes).
View 302 unnecessary modules by category
-
es.typed-array.* 39 -
es.array.* 37 -
es.string.* 36 -
es.object.* 28 -
es.math.* 18 -
web.* 17 -
es.symbol.* 15 -
es.reflect.* 14 -
es.number.* 13 -
es.date.* 8 -
esnext.array.* 8 -
es.regexp.* 7 -
esnext.set.* 7 -
es.array-buffer.* 6 -
esnext.typed-array.* 6 -
es.promise.* 5 -
es.set.* 5 -
esnext.string.* 4 -
es.function.* 3 -
esnext.array-buffer.* 3 -
esnext.promise.* 3 -
es.error.* 2 -
es.aggregate-error.* 2 -
es.map.* 2 -
esnext.object.* 2 -
es.data-view.* 1 -
es.escape.* 1 -
es.global-this.* 1 -
es.json.* 1 -
es.parse-float.* 1 -
es.parse-int.* 1 -
es.unescape.* 1 -
es.weak-map.* 1 -
es.weak-set.* 1 -
esnext.aggregate-error.* 1 -
esnext.global-this.* 1 -
esnext.map.* 1
Duplicate Dependencies
12 duplicate dependencies
detected across this starter's node_modules.
View 12 duplicate dependencies
- debug
[duplicate dependency] debug has 2 installed versions:
4.4.3 via the following 10 package(s) @babel/traverse@7.29.0, @babel/core@7.29.0, @eslint/config-array@0.21.1, @eslint/eslintrc@3.3.3, eslint@9.39.2, eslint-import-resolver-typescript@3.10.1, @typescript-eslint/project-service@8.55.0, @typescript-eslint/typescript-estree@8.55.0, @typescript-eslint/parser@8.55.0, @typescript-eslint/type-utils@8.55.0
3.2.7 via the following 3 package(s) eslint-import-resolver-node@0.3.9, eslint-plugin-import@2.32.0, eslint-module-utils@2.12.1
๐ก Suggestions
- Consider standardizing on version 4.4.3 as this version is the most commonly used.
- Consider upgrading consuming packages as this may resolve this duplicate version.
- json5
[duplicate dependency] json5 has 2 installed versions:
2.2.3 via the following 1 package(s) @babel/core@7.29.0
1.0.2 via the following 1 package(s) tsconfig-paths@3.15.0
๐ก Suggestions
- Consider upgrading consuming packages as this may resolve this duplicate version.
- semver
[duplicate dependency] semver has 2 installed versions:
6.3.1 via the following 4 package(s) @babel/helper-compilation-targets@7.28.6, @babel/core@7.29.0, eslint-plugin-import@2.32.0, eslint-plugin-react@7.37.5
7.7.4 via the following 3 package(s) sharp@0.34.5, is-bun-module@2.0.0, @typescript-eslint/typescript-estree@8.55.0
๐ก Suggestions
- Consider standardizing on version 6.3.1 as this version is the most commonly used.
- Consider upgrading consuming packages as this may resolve this duplicate version.
- eslint-visitor-keys
[duplicate dependency] eslint-visitor-keys has 2 installed versions:
3.4.3 via the following 1 package(s) @eslint-community/eslint-utils@4.9.1
4.2.1 via the following 3 package(s) espree@10.4.0, eslint@9.39.2, @typescript-eslint/visitor-keys@8.55.0
๐ก Suggestions
- Consider standardizing on version 4.2.1 as this version is the most commonly used.
- Consider upgrading consuming packages as this may resolve this duplicate version.
- minimatch
[duplicate dependency] minimatch has 2 installed versions:
3.1.2 via the following 6 package(s) @eslint/config-array@0.21.1, @eslint/eslintrc@3.3.3, eslint@9.39.2, eslint-plugin-import@2.32.0, eslint-plugin-jsx-a11y@6.10.2, eslint-plugin-react@7.37.5
9.0.5 via the following 1 package(s) @typescript-eslint/typescript-estree@8.55.0
๐ก Suggestions
- Consider standardizing on version 3.1.2 as this version is the most commonly used.
- Consider upgrading consuming packages as this may resolve this duplicate version.
- globals
[duplicate dependency] globals has 2 installed versions:
14.0.0 via the following 1 package(s) @eslint/eslintrc@3.3.3
16.4.0 via the following 1 package(s) eslint-config-next@16.1.1
๐ก Suggestions
- Consider upgrading consuming packages as this may resolve this duplicate version.
- ignore
[duplicate dependency] ignore has 2 installed versions:
5.3.2 via the following 2 package(s) @eslint/eslintrc@3.3.3, eslint@9.39.2
7.0.5 via the following 1 package(s) @typescript-eslint/eslint-plugin@8.55.0
๐ก Suggestions
- Consider standardizing on version 5.3.2 as this version is the most commonly used.
- Consider upgrading consuming packages as this may resolve this duplicate version.
- postcss
[duplicate dependency] postcss has 2 installed versions:
8.5.6 via the following 1 package(s) @tailwindcss/postcss@4.1.18
8.4.31 via the following 1 package(s) next@16.1.1
๐ก Suggestions
- Consider upgrading consuming packages as this may resolve this duplicate version.
- brace-expansion
[duplicate dependency] brace-expansion has 2 installed versions:
1.1.12 via the following 1 package(s) minimatch@3.1.2
2.0.2 via the following 1 package(s) minimatch@9.0.5
๐ก Suggestions
- Consider upgrading consuming packages as this may resolve this duplicate version.
- resolve
[duplicate dependency] resolve has 2 installed versions:
1.22.11 via the following 1 package(s) eslint-import-resolver-node@0.3.9
2.0.0-next.5 via the following 1 package(s) eslint-plugin-react@7.37.5
๐ก Suggestions
- Consider upgrading consuming packages as this may resolve this duplicate version.
- glob-parent
[duplicate dependency] glob-parent has 2 installed versions:
6.0.2 via the following 1 package(s) eslint@9.39.2
5.1.2 via the following 1 package(s) fast-glob@3.3.1
๐ก Suggestions
- Consider upgrading consuming packages as this may resolve this duplicate version.
- picomatch
[duplicate dependency] picomatch has 2 installed versions:
4.0.3 via the following 2 package(s) fdir@6.5.0, tinyglobby@0.2.15
2.3.1 via the following 1 package(s) micromatch@4.0.8
๐ก Suggestions
- Consider standardizing on version 4.0.3 as this version is the most commonly used.
- Consider upgrading consuming packages as this may resolve this duplicate version.
Runtime Performance
Client Side Rendered Tests
| Framework | First Paint | FCP | INP |
| Next.js | 347.2ms | 347.24ms | 20.16ms |
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 |
| Next.js | 132.6ms | 132.6ms | 17.31ms |
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 |
| Next.js | 217 | 4.819ms | 199.57kb | 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 |
| Next.js | 34.4 | 1 | 2154ms | 4693ms | 4754ms | 1,000 |
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