Overview

Benchmarks

Benchmarks are part of Mreact's development loop. They are used to watch primitive runtime behavior, browser DOM costs, app-router throughput, client bundle size, route artifact shape, and deployment startup paths.

What we measure

  • Primitive DOM work - Keyed list operations, row selection, event target creation, and memory-sensitive DOM cases are separated from lower-level reactivity microbenchmarks. For cross-framework keyed DOM comparisons, the official krausest/js-framework-benchmark harness is the reference, because it maintains the peer-framework adapters and keyed validation rules.
  • Primitive reactivity microbenchmarks - Source writes, text bindings, computed fan-out, and computed fan-in stay in the repository as local regression signals. They are useful for Mreact runtime development, but they are not a replacement for official DOM benchmark results from the krausest harness.
  • Primitive framework adapters - Marko, Vue, Svelte, Angular, Qwik, React, Solid, and Mreact run local primitive cases for context. Numbers from peer-framework adapters in the local runner are indicative only; the official harness is the reference for cross-framework comparisons.
  • Browser runtime behavior - How the same DOM-heavy primitive cases behave in real Chromium rather than only in the server-side benchmark harness.
  • App router and deployment paths - How server rendering, streaming, static cache hits, middleware, route matching, cold starts, build time, and adapter targets behave under app-router workloads.
  • Router framework adapters - Marko Run, Nuxt, SvelteKit, Analog, Qwik City, SolidStart, TanStack Start, Next.js App Router, and Mreact app router run production router fixtures where practical.
  • Client bundle shape - How much JavaScript is shipped for server-only routes and interactive routes after gzip compression.
  • Route artifact boundaries - Whether middleware, redirects, loaders, server actions, layouts, and render modules stay separated enough to avoid unnecessary imports.
  • Package-level microbenchmarks - Store, virtual list, query, forms, and auth microbenchmarks catch non-router regressions even when they are not rendered as public ranking cards.

How to read results

Treat benchmark numbers as trend signals, not universal promises. Compare runs with the same Node version, adapter target, route set, and build mode before drawing conclusions.

Resumability-oriented frameworks such as Qwik and Marko are designed around delaying or avoiding client-side activation, not only around already-active update paths. Primitive DOM-update cases mostly measure already-active update paths, and the browser interaction cases use small synthetic routes, so read interaction timing together with shipped JavaScript size, startup work, and whether unused UI needs to activate at all.

For keyed table operations such as create rows, replace rows, partial update, select row, append rows, remove row, swap/reorder rows, and clear rows, the source of truth is the official krausest/js-framework-benchmark harness. The local primitive runner remains useful for quick regression checks and experiments, but it is not an authoritative cross-framework comparison.

The keyed table results include two React-compatibility Mreact fixtures. mreact-react-compat is the compiler-lowered path: the source stays React-compatible JSX, and the Mreact compiler lowers proven-safe state text, prop, and event bindings into reactive DOM operations. mreact-react-compat-vdom is the virtual-DOM compatibility path: the same app shape runs through the React-compatible runtime without those DOM-binding lowerings. Compare the two to separate compatibility runtime cost from the compiler's normal DOM-binding optimizations.

Latest results

Run 2026-07-03/001

Complete ranking cards from the latest benchmark Markdown reports. These cards mirror the ranking sections in the repository artifacts without trimming the result set.

Source: benchmarks/results/2026-07-03/001

View run on GitHub

Date
2026-07-03
Commit
cf49e19
Node
v24.18.0
CPU
Intel(R) Xeon(R) Platinum 8370C CPU @ 2.80GHz, 4 cores

Categories

Frameworks

js-framework-benchmark keyed DOM benchmarks

js-framework-benchmark.md / 13 ranking cards / View source on GitHub / Official js-framework-benchmark harness

create rowsms

9 entries

Interactivity

#1 mreact66.4bestScript6.2Paint58.7
#2 marko66.9+0.75%Script7.2Paint58.5
#3 solid67.3+1.36%Script7.3Paint58.8
#4 svelte69.6+4.82%Script10.6Paint58
#5 vue80.3+20.93%Script19.8Paint59.3
#6 react-hooks84+26.51%Script21.6Paint61.1
#7 mreact-react-compat84.7+27.56%Script23.5Paint59.8
#8 angular-cf95.7+44.13%Script18.6Paint60.1
#9 mreact-react-compat-vdom96.4+45.18%Script35.9Paint59

replace all rowsms

9 entries

Interactivity

#1 solid74.2bestScript13.4Paint59.5
#2 marko74.5+0.4%Script13.9Paint59.5
#3 mreact75.4+1.62%Script15.5Paint59.4
#4 svelte77.7+4.72%Script16.3Paint59.7
#5 mreact-react-compat85.1+14.69%Script24.1Paint59.7
#6 vue85.4+15.09%Script22.6Paint60.7
#7 react-hooks93.9+26.55%Script31Paint61.4
#8 mreact-react-compat-vdom97.6+31.54%Script36.3Paint59.9
#9 angular-cf104.9+41.37%Script26.9Paint62.9

partial updatems

9 entries

SSR

#1 angular-cf38.2bestScript3Paint34.2
#2 mreact40+4.71%Script1.6Paint34
#3 marko41+7.33%Script3.8Paint32.5
#4 svelte42.3+10.73%Script3.9Paint34.5
#5 solid42.6+11.52%Script2.7Paint34.8
#6 mreact-react-compat47.8+25.13%Script7.9Paint34.5
#7 react-hooks48.5+26.96%Script10.7Paint33.8
#8 vue49.1+28.53%Script6.4Paint37.3
#9 mreact-react-compat-vdom60+57.07%Script19.5Paint36.2

select rowms

9 entries

Interactivity

#1 mreact9.4bestScript1Paint6.6
#2 marko10.1+7.45%Script1.1Paint7
#3 solid10.8+14.89%Script1.9Paint7
#4 vue11.3+20.21%Script2.6Paint6.7
#5 angular-cf14.6+55.32%Script4.3Paint8.3
#6 react-hooks15.6+65.96%Script6Paint7.3
#7 svelte15.7+67.02%Script6.6Paint7
#8 mreact-react-compat16+70.21%Script6.5Paint7.4
#9 mreact-react-compat-vdom16.8+78.72%Script7.1Paint7.3

swap rowsms

9 entries

Interactivity

#1 marko47.1bestScript2.9Paint39.5
#2 mreact47.3+0.42%Script1.8Paint41.4
#3 svelte47.4+0.64%Script3.8Paint39.5
#4 solid47.6+1.06%Script1.9Paint40.2
#5 angular-cf48.1+2.12%Script2.9Paint42
#6 vue48.4+2.76%Script3.2Paint40.8
#7 mreact-react-compat54.8+16.35%Script9.7Paint40
#8 mreact-react-compat-vdom64+35.88%Script17.4Paint41
#9 react-hooks309+556.05%Script41.5Paint259.5

remove rowms

9 entries

Interactivity

#1 angular-cf32.5bestScript1.8Paint30
#2 solid35.4+8.92%Script0.9Paint32.1
#3 mreact35.7+9.85%Script0.9Paint32.5
#4 marko36.4+12%Script1.1Paint32.6
#5 svelte36.5+12.31%Script1.6Paint32
#6 react-hooks37.7+16%Script2.6Paint32.3
#7 mreact-react-compat37.9+16.62%Script3.1Paint32.3
#8 vue39.5+21.54%Script4.8Paint32.5
#9 mreact-react-compat-vdom40+23.08%Script4.7Paint32.7

create many rowsms

9 entries

Interactivity

#1 mreact719.6bestScript74.4Paint636.3
#2 marko725+0.75%Script80.5Paint634.9
#3 solid727.4+1.08%Script71Paint646.7
#4 svelte740.5+2.9%Script92.7Paint639.3
#5 vue824.1+14.52%Script153.7Paint659.2
#6 mreact-react-compat859.3+19.41%Script235Paint614
#7 mreact-react-compat-vdom919.4+27.77%Script276Paint632.5
#8 angular-cf929.6+29.18%Script191.3Paint659.1
#9 react-hooks1109.3+54.16%Script427.1Paint667.2

append rows to large tablems

9 entries

Interactivity

#1 mreact76.8bestScript7.7Paint67.2
#2 marko78.7+2.47%Script9Paint67.9
#3 solid79.6+3.65%Script8.8Paint69.4
#4 svelte80.5+4.82%Script10.6Paint68.6
#5 vue85.6+11.46%Script16.5Paint67.4
#6 mreact-react-compat91.6+19.27%Script24.1Paint65.8
#7 react-hooks92.4+20.31%Script22.4Paint67.9
#8 angular-cf98.2+27.86%Script16.1Paint67.7
#9 mreact-react-compat-vdom100.5+30.86%Script31.9Paint66.6

clear rowsms

9 entries

Interactivity

#1 marko25.1bestScript20.4Paint3.1
#2 mreact25.7+2.39%Script21.3Paint3.3
#3 svelte28.9+15.14%Script23.8Paint3.8
#4 solid29.8+18.73%Script25.1Paint3.1
#5 mreact-react-compat-vdom34.1+35.86%Script29.6Paint3.3
#6 vue34.8+38.65%Script30.6Paint3
#7 mreact-react-compat39.1+55.78%Script34.5Paint2.9
#8 react-hooks45.4+80.88%Script40.9Paint3.4
#9 angular-cf49.3+96.41%Script44.6Paint3.5

ready memoryKB

9 entries

Memory

#1 solid1046best
#2 marko1089+4.07%
#3 mreact1139+8.86%
#4 svelte1233+17.87%
#5 vue1360+29.96%
#6 mreact-react-compat-vdom1418+35.56%
#7 mreact-react-compat1425+36.2%
#8 react-hooks1657+58.4%
#9 angular-cf2108+101.48%

run memoryKB

9 entries

Memory

#1 mreact2890best
#2 marko2914+0.84%
#3 solid3194+10.52%
#4 svelte3588+24.14%
#5 vue4569+58.08%
#6 react-hooks5017+73.6%
#7 mreact-react-compat-vdom5042+74.48%
#8 angular-cf5185+79.42%
#9 mreact-react-compat5451+88.6%

repeated clear memoryKB

9 entries

Memory

#1 solid1266best
#2 marko1366+7.91%
#3 mreact1402+10.73%
#4 svelte1576+24.47%
#5 vue1755+38.57%
#6 mreact-react-compat2008+58.59%
#7 react-hooks2521+99.12%
#8 mreact-react-compat-vdom2605+105.73%
#9 angular-cf2695+112.83%

total byte weightkB

9 entries

SSR

#1 solid4.5best
#2 marko5+11.11%
#3 mreact9.9+120%
#4 svelte14.3+217.78%
#5 vue23.9+431.11%
#6 mreact-react-compat-vdom33+633.33%
#7 mreact-react-compat35+677.78%
#8 angular-cf44.5+888.89%
#9 react-hooks51.4+1042.22%

Router benchmarks

router.md / 37 ranking cards / View source on GitHub

app client bundle gzip bytes (server-only page)gzip bytes

13 entries

SizeClientProduction

Measures gzip-compressed client JavaScript shipped for a route with no user-authored interactivity.

#1 svelte-kit0
#1 mreact-app-router0
#1 mreact-app-router+mreact react-compat0
#1 mreact-app-router+log enabled0
#5 marko-run1598
#6 solid-start20211
#7 qwik-city25539
#8 qwik-router-v251246
#9 tanstack-start-solid57974
#10 nuxt65534
#11 analog90673
#12 tanstack-start104797
#13 next-app-router145595

app client bundle gzip bytes (interactive page)gzip bytes

13 entries

SizeClientProduction

Measures gzip-compressed client JavaScript shipped for a minimal button-and-state interactive route.

#1 marko-run2509best
#2 mreact-app-router11600+362.34%
#2 mreact-app-router+log enabled11600+362.34%
#4 solid-start19242+666.92%
#5 svelte-kit32289+1186.93%
#6 qwik-city35079+1298.13%
#7 mreact-app-router+mreact react-compat41350+1548.07%
#8 qwik-router-v252899+2008.37%
#9 tanstack-start-solid56111+2136.39%
#10 nuxt68098+2614.15%
#11 analog90841+3520.61%
#12 tanstack-start103195+4012.99%
#13 next-app-router149265+5849.18%

app client bundle gzip bytes (interactive page, minimal opt-out)gzip bytes

13 entries

SizeClientProduction

Measures the same interactive route while opting out of optional client navigation runtime where the framework supports it.

#1 marko-run2509best
#2 mreact-app-router6646+164.89%
#2 mreact-app-router+log enabled6646+164.89%
#4 solid-start19242+666.92%
#5 svelte-kit32289+1186.93%
#6 qwik-city35079+1298.13%
#7 mreact-app-router+mreact react-compat36531+1356%
#8 qwik-router-v252899+2008.37%
#9 tanstack-start-solid56111+2136.39%
#10 nuxt68103+2614.35%
#11 analog90841+3520.61%
#12 tanstack-start103195+4012.99%
#13 next-app-router149265+5849.18%

app render 1000 nodesops/sec

13 entries

SSRServerProduction

Renders a production app route that emits 1,000 simple text spans.

#1 mreact-app-router+log enabled592best
#1 mreact-app-router+mreact react-compat5920%
#3 mreact-app-router578-2.36%
#4 nuxt418-29.39%
#5 marko-run398-32.77%
#6 tanstack-start381-35.64%
#7 svelte-kit378-36.15%
#8 qwik-city315-46.79%
#9 solid-start270-54.39%
#10 qwik-router-v2260-56.08%
#11 tanstack-start-solid228-61.49%
#12 analog103-82.6%
#13 next-app-router76-87.16%

app streaming 1000 nodesops/sec

13 entries

SSRServerProduction

Streams a production app route with 1,000 simple text spans and validates the complete response body.

#1 mreact-app-router563best
#2 mreact-app-router+log enabled560-0.53%
#3 mreact-app-router+mreact react-compat557-1.07%
#4 marko-run476-15.45%
#5 nuxt449-20.25%
#6 tanstack-start414-26.47%
#7 svelte-kit406-27.89%
#8 solid-start276-50.98%
#9 tanstack-start-solid241-57.19%
#10 qwik-city223-60.39%
#11 qwik-router-v2176-68.74%
#12 analog104-81.53%
#13 next-app-router78-86.15%

app streaming first byte 1000 nodesms

12 entries

SSRServerProduction

Measures elapsed time until fetch resolves response headers for the real streaming route.

#1 mreact-app-router+mreact react-compat2.1556best
#2 mreact-app-router2.1926+1.72%
#3 mreact-app-router+log enabled2.453+13.8%
#4 marko-run2.8108+30.4%
#5 solid-start3.7616+74.5%
#6 qwik-city3.9349+82.54%
#7 next-app-router4.6129+114%
#8 nuxt53.3576+2375.3%
#9 tanstack-start53.7714+2394.5%
#10 svelte-kit53.8042+2396.02%
#11 tanstack-start-solid55.4857+2474.03%
#12 qwik-router-v257.6997+2576.74%

app streaming first chunk 1000 nodesms

12 entries

SSRServerProduction

Measures elapsed time until the first response body chunk arrives for the real streaming route.

#1 mreact-app-router2.1311best
#2 mreact-app-router+log enabled2.3111+8.45%
#3 mreact-app-router+mreact react-compat2.3958+12.42%
#4 marko-run2.8335+32.96%
#5 solid-start3.699+73.57%
#6 qwik-city3.862+81.22%
#7 next-app-router5.061+137.48%
#8 nuxt53.4573+2408.44%
#9 tanstack-start54.0348+2435.54%
#10 svelte-kit54.0711+2437.24%
#11 tanstack-start-solid55.6476+2511.21%
#12 qwik-router-v257.004+2574.86%

app streaming full body 1000 nodesms

12 entries

SSRServerProduction

Measures elapsed time until the complete real streaming response body is consumed and validated.

#1 mreact-app-router52.651best
#2 mreact-app-router+mreact react-compat52.9759+0.62%
#3 mreact-app-router+log enabled53.0081+0.68%
#4 solid-start53.1427+0.93%
#5 nuxt53.4705+1.56%
#6 marko-run53.7788+2.14%
#7 tanstack-start54.082+2.72%
#8 svelte-kit54.1691+2.88%
#9 tanstack-start-solid55.4774+5.37%
#10 qwik-city55.6696+5.73%
#11 qwik-router-v257.242+8.72%
#12 next-app-router62.5412+18.78%

app real streaming 1000 nodes (async 50ms)ms

12 entries

SSRServerProduction

Measures complete response latency for a route whose body waits on a 50 ms async boundary.

#1 mreact-app-router52.7926best
#2 mreact-app-router+log enabled52.9078+0.22%
#3 solid-start52.9515+0.3%
#4 mreact-app-router+mreact react-compat53.3354+1.03%
#5 nuxt53.4222+1.19%
#6 marko-run53.7523+1.82%
#7 tanstack-start53.9119+2.12%
#8 svelte-kit54.2453+2.75%
#9 tanstack-start-solid55.0377+4.25%
#10 qwik-city55.8454+5.78%
#11 qwik-router-v257.1649+8.28%
#12 next-app-router62.2791+17.97%

app parallel async boundaries 2x50msms

12 entries

SSRServerProduction

Measures complete response latency for two sibling 50 ms async boundaries; parallel renderers stay near one boundary.

#1 solid-start52.403best
#2 mreact-app-router+mreact react-compat52.6942+0.56%
#3 mreact-app-router52.7703+0.7%
#4 mreact-app-router+log enabled52.8302+0.82%
#5 svelte-kit53.1664+1.46%
#6 marko-run53.3088+1.73%
#7 tanstack-start53.3343+1.78%
#8 nuxt53.3485+1.8%
#9 next-app-router54.1984+3.43%
#10 qwik-city54.6429+4.27%
#11 tanstack-start-solid54.8648+4.7%
#12 qwik-router-v255.8423+6.56%

app static cached route 1000 nodesops/sec

7 entries

SSRServerProduction

Renders a static-cacheable app route with 1,000 simple text spans after the production server has warmed it.

#1 mreact-app-router+mreact react-compat566best
#2 mreact-app-router+log enabled565-0.18%
#3 mreact-app-router557-1.59%
#4 nuxt484-14.49%
#5 svelte-kit413-27.03%
#6 next-app-router285-49.65%
#7 analog109-80.74%

app dynamic-attr grid 200 cellsops/sec

13 entries

SSRServerProduction

Renders 200 cells with many dynamic escaped attributes, inline style values, and text content.

#1 mreact-app-router522best
#2 mreact-app-router+log enabled521-0.19%
#3 mreact-app-router+mreact react-compat456-12.64%
#4 nuxt402-22.99%
#5 marko-run361-30.84%
#6 svelte-kit334-36.02%
#7 tanstack-start322-38.31%
#8 solid-start289-44.64%
#9 tanstack-start-solid252-51.72%
#10 qwik-city197-62.26%
#11 qwik-router-v2154-70.5%
#12 analog120-77.01%
#13 next-app-router99-81.03%

app dynamic route params dataops/sec

13 entries

RoutingServerProduction

Renders a dynamic route that combines route parameters with server data before producing HTML.

#1 mreact-app-router+log enabled508best
#2 mreact-app-router502-1.18%
#3 mreact-app-router+mreact react-compat462-9.06%
#4 nuxt391-23.03%
#5 marko-run362-28.74%
#6 svelte-kit330-35.04%
#7 tanstack-start296-41.73%
#8 solid-start282-44.49%
#9 tanstack-start-solid247-51.38%
#10 qwik-city188-62.99%
#11 qwik-router-v2151-70.28%
#12 analog114-77.56%
#13 next-app-router93-81.69%

app concurrent throughput 100 connectionsops/sec

13 entries

ConcurrencyServerProduction

Runs a fixed burst against the production fixture with up to 100 concurrent requests and reports sustained request throughput.

#1 mreact-app-router+mreact react-compat1147.3014best
#2 mreact-app-router+log enabled1122.5704-2.16%
#3 mreact-app-router1061.3868-7.49%
#4 marko-run950.5817-17.15%
#5 tanstack-start670.5745-41.55%
#6 nuxt665.8351-41.97%
#7 solid-start634.7787-44.67%
#8 svelte-kit625.8861-45.45%
#9 qwik-city550.8343-51.99%
#10 tanstack-start-solid462.2529-59.71%
#11 qwik-router-v2282.7769-75.35%
#12 analog121.6535-89.4%
#13 next-app-router81.1253-92.93%

app concurrent p99 latency 100 connectionsms

13 entries

ConcurrencyServerProduction

Runs the same concurrent request burst and reports per-request p99 latency, exposing event-loop stalls hidden by sequential tinybench runs.

#1 marko-run134.0561best
#2 mreact-app-router+mreact react-compat155.2642+15.82%
#3 mreact-app-router+log enabled166.0612+23.87%
#4 mreact-app-router175.6096+31%
#5 nuxt192.787+43.81%
#6 tanstack-start199.2819+48.66%
#7 solid-start289.1809+115.72%
#8 svelte-kit311.9802+132.72%
#9 qwik-city352.6474+163.06%
#10 tanstack-start-solid414.4402+209.15%
#11 qwik-router-v2624.4924+365.84%
#12 analog903.099+573.67%
#13 next-app-router2454.3178+1730.81%

app concurrent RSS delta 100 connectionsbytes

13 entries

ConcurrencyServerProduction

Reports RSS growth across the concurrent request burst so sustained-load memory trends are visible in router benchmark output.

#1 nuxt0
#1 svelte-kit0
#1 qwik-city0
#1 qwik-router-v20
#1 tanstack-start-solid0
#1 mreact-app-router0
#7 analog131072
#8 mreact-app-router+mreact react-compat262144
#9 marko-run393216
#10 mreact-app-router+log enabled2228224
#11 tanstack-start2752512
#12 solid-start24641536
#13 next-app-router107520000

app loader client navigation route-to-routems

8 entries

NavigationClientProduction

Measures browser client navigation to a route with loader data, covering data-bearing SPA transitions.

#1 mreact-app-router23.8best
#2 mreact-app-router+log enabled24.7+3.78%
#3 mreact-app-router+mreact react-compat33.1+39.08%
#4 next-app-router39.1+64.29%
#5 solid-start44.1+85.29%
#6 tanstack-start57+139.5%
#7 qwik-router-v299.2+316.81%
#8 qwik-city105.8+344.54%

app client navigation back-forward restorems

11 entries

NavigationClientProduction

Measures browser back-forward restoration after SPA navigation so history snapshot regressions are visible.

#1 solid-start7.6best
#2 mreact-app-router+mreact react-compat7.7+1.32%
#2 mreact-app-router+log enabled7.7+1.32%
#4 mreact-app-router7.9+3.95%
#5 svelte-kit8.4+10.53%
#6 tanstack-start11+44.74%
#6 next-app-router11+44.74%
#8 analog12.6+65.79%
#9 nuxt31.8+318.42%
#10 qwik-router-v258.3+667.11%
#11 qwik-city103.4+1260.53%

app client navigation route-to-routems

11 entries

NavigationClientProduction

Measures route-to-route client navigation latency in a real browser when the adapter provides a browser probe.

#1 mreact-app-router+mreact react-compat34.5best
#2 mreact-app-router+log enabled35+1.45%
#3 mreact-app-router35.1+1.74%
#4 svelte-kit52.4+51.88%
#5 solid-start54.8+58.84%
#6 analog55.4+60.58%
#7 tanstack-start57.1+65.51%
#8 next-app-router57.6+66.96%
#9 nuxt106+207.25%
#10 qwik-city116.2+236.81%
#11 qwik-router-v2117.3+240%

app initial page load JS before interactionms

12 entries

InteractivityClientBrowserProduction

Measures page load time until the interactive route is visible and idle before any user interaction.

#1 marko-run544.7986best
#2 solid-start548.9108+0.75%
#3 mreact-app-router553.1273+1.53%
#4 mreact-app-router+log enabled553.447+1.59%
#5 tanstack-start556.3102+2.11%
#6 mreact-app-router+mreact react-compat559.1678+2.64%
#7 svelte-kit565.3368+3.77%
#8 qwik-city574.6391+5.48%
#9 qwik-router-v2579.996+6.46%
#10 nuxt594.7482+9.17%
#11 analog614.1298+12.73%
#12 next-app-router640.016+17.48%

app first interaction from DOMContentLoadedms

12 entries

InteractivityClientBrowserProduction

Measures the first click-to-visible-update latency immediately after DOMContentLoaded without waiting for network idle.

#1 solid-start23.9best
#2 analog24.2+1.26%
#3 mreact-app-router+mreact react-compat26.5+10.88%
#4 mreact-app-router+log enabled33.2+38.91%
#5 mreact-app-router34.9+46.03%
#6 marko-run35.6+48.95%
#7 svelte-kit37.5+56.9%
#8 nuxt38.4+60.67%
#9 tanstack-start40.4+69.04%
#10 next-app-router48.8+104.18%
#11 qwik-city64.2+168.62%
#12 qwik-router-v264.5+169.87%

app first interaction after networkidlems

12 entries

InteractivityClientBrowserProduction

Measures the first click-to-visible-update latency after the interactive route has reached network idle.

#1 mreact-app-router+log enabled20.4best
#2 solid-start21.3+4.41%
#3 marko-run23.3+14.22%
#4 mreact-app-router+mreact react-compat24.7+21.08%
#5 svelte-kit25.9+26.96%
#6 analog27.6+35.29%
#7 nuxt27.9+36.76%
#8 mreact-app-router29.2+43.14%
#9 tanstack-start30.5+49.51%
#10 next-app-router31.4+53.92%
#11 qwik-city47.7+133.82%
#12 qwik-router-v252+154.9%

app second interaction latencyms

12 entries

InteractivityClientBrowserProduction

Measures the second click-to-visible-update latency after the route has already handled one client interaction.

#1 tanstack-start29.5best
#2 next-app-router29.9+1.36%
#3 mreact-app-router+mreact react-compat30+1.69%
#4 svelte-kit30.6+3.73%
#5 analog30.7+4.07%
#5 mreact-app-router+log enabled30.7+4.07%
#7 mreact-app-router30.8+4.41%
#8 solid-start31.1+5.42%
#9 nuxt31.2+5.76%
#10 marko-run31.4+6.44%
#11 qwik-router-v241.7+41.36%
#12 qwik-city62.8+112.88%

app SSR HTML gzip bytes 1000 nodesgzip bytes

13 entries

SizeServerProduction

Measures gzip-compressed HTML payload bytes for the 1,000-node SSR route, complementing client bundle size cases.

#1 marko-run2292best
#2 mreact-app-router2301+0.39%
#2 mreact-app-router+mreact react-compat2301+0.39%
#2 mreact-app-router+log enabled2301+0.39%
#5 analog2664+16.23%
#6 svelte-kit2749+19.94%
#7 nuxt2893+26.22%
#8 tanstack-start3515+53.36%
#9 qwik-city6103+166.27%
#10 qwik-router-v26926+202.18%
#11 solid-start9346+307.77%
#12 tanstack-start-solid9785+326.92%
#13 next-app-router14923+551.09%

app build output gzip bytesgzip bytes

13 entries

SizeServerProduction

Measures gzip-compressed production build output size when the adapter exposes build artifacts.

#1 mreact-app-router66195best
#2 mreact-app-router+log enabled66244+0.07%
#3 marko-run77260+16.72%
#4 mreact-app-router+mreact react-compat120811+82.51%
#5 tanstack-start-solid152765+130.78%
#6 tanstack-start160617+142.64%
#7 solid-start167588+153.17%
#8 svelte-kit177864+168.7%
#9 qwik-router-v2181242+173.8%
#10 qwik-city279470+322.19%
#11 next-app-router419581+533.86%
#12 analog529968+700.62%
#13 nuxt550411+731.5%

app hydration 100 islandsms

3 entries

InteractivityClientBrowserProduction

Loads an app route with 100 independently interactive islands and reports time until all islands can update in real Chromium. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled837.6077best
#2 mreact-app-router858.0573+2.44%
#3 mreact-app-router+mreact react-compat865.7519+3.36%

app dev cold startms

3 entries

DevServerDevelopment

Starts the framework dev server for a minimal app and reports server readiness latency. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled4.0825best
#2 mreact-app-router+mreact react-compat4.6258+13.31%
#3 mreact-app-router16.1993+296.8%

app dev first request latencyms

3 entries

DevServerDevelopment

Requests a minimal app route from a warm dev server and reports first request latency. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled36.6452best
#2 mreact-app-router61.0391+66.57%
#3 mreact-app-router+mreact react-compat94.3738+157.53%

app dev HMR update latencyms

3 entries

DevServerDevelopment

Edits a route module while the dev server is running and reports time until the changed response is observable. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled31.1144best
#2 mreact-app-router33.1397+6.51%
#3 mreact-app-router+mreact react-compat81.8751+163.14%

app 1000 route match latencyms

3 entries

RoutingServerProduction

Builds a 1,000-route app and reports request latency for a route near the end of the route table. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router9.7518best
#2 mreact-app-router+log enabled16.4448+68.63%
#3 mreact-app-router+mreact react-compat26.1795+168.46%

app 1000 route cold startms

3 entries

StartupServerProduction

Builds a 1,000-route app and reports production server cold-start latency for that route scale. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router408.5104best
#2 mreact-app-router+log enabled414.3366+1.43%
#3 mreact-app-router+mreact react-compat421.5816+3.2%

app 1000 route build timems

3 entries

BuildServerProduction

Reports production build time for a 1,000-route app to catch route-count scaling regressions. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router13407.7018best
#2 mreact-app-router+mreact react-compat18719.8217+39.62%
#3 mreact-app-router+log enabled21092.3888+57.32%

app 1000 route RSS deltabytes

3 entries

MemoryServerProduction

Reports process RSS growth while building and serving a 1,000-route app. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled324730880best
#2 mreact-app-router+mreact react-compat491298816+51.29%
#3 mreact-app-router622211072+91.61%

app server action form POST roundtripms

3 entries

SSRServerProduction

Renders a form with an inferred server action, submits the encoded form POST, and reports action roundtrip latency. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled52.5057best
#2 mreact-app-router+mreact react-compat57.0804+8.71%
#3 mreact-app-router62.1585+18.38%

app nested layouts depth 5ms

3 entries

RoutingServerProduction

Renders a route under five nested layouts, guarding against sequential layout shell regressions. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled43.6008best
#2 mreact-app-router44.6465+2.4%
#3 mreact-app-router+mreact react-compat54.1445+24.18%

app Cloudflare Worker request latencyms

3 entries

SSRServerProduction

Builds the Cloudflare Pages worker bundle and reports request latency through its exported fetch handler. A workerd/Miniflare harness should replace this fallback once the local workerd path-resolution failure is fixed. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+log enabled2.2967best
#2 mreact-app-router2.5635+11.62%
#3 mreact-app-router+mreact react-compat3.0709+33.71%

app server cold startms

3 entries

StartupServerProduction

Measures production server cold-start latency when the adapter can isolate startup from build work. This section currently compares mreact app-router variants only; it is not a cross-framework ranking.

#1 mreact-app-router+mreact react-compat260.3382best
#2 mreact-app-router+log enabled261.0097+0.26%
#3 mreact-app-router270.2827+3.82%

Primitive DOM benchmarks

primitive.md / 3 ranking cards / View source on GitHub

keyed reverse 1k rowsms

10 entries

Interactivity

Reverses 1,000 keyed rows and verifies that DOM node identity is preserved.

#1 solid4.0003best
#2 solid-v24.0809+2.01%
#3 vue4.5164+12.9%
#4 angular5.3099+32.74%
#5 mreact react-compat5.6263+40.65%
#6 react6.1128+52.81%
#7 mreact6.5796+64.48%
#8 marko7.1098+77.73%
#9 qwik9.0346+125.85%
#10 svelte39.6519+891.22%

create 1k event targetsms

10 entries

Interactivity

Creates 1,000 button event targets and measures initial interactive wiring cost without dispatching events.

#1 solid11.717best
#2 mreact12.1722+3.88%
#3 react12.9065+10.15%
#4 solid-v213.8128+17.89%
#5 mreact react-compat15.7658+34.55%
#6 vue15.9226+35.89%
#7 svelte17.7783+51.73%
#8 qwik18.2186+55.49%
#9 angular20.7289+76.91%
#10 marko23.1278+97.39%

repeated create update clear memorybytes

10 entries

Memory

Reports heap growth after repeatedly creating, updating, and clearing 1,000-row lists.

#1 svelte23184best
#2 mreact41696+79.85%
#3 qwik61712+166.18%
#4 solid70376+203.55%
#5 solid-v270488+204.04%
#6 marko81368+250.97%
#7 mreact react-compat287320+1139.3%
#8 vue330720+1326.5%
#9 react343712+1382.54%
#10 angular372096+1504.97%

Primitive reactivity microbenchmarks

primitive.md / 5 ranking cards / View source on GitHub

source write with subscriber 1kms

3 entries

Interactivity

Updates 1,000 fine-grained source values when each source has one live non-DOM subscriber, separating direct source write overhead from aggregate computed fan-in and framework-level array update work.

#1 mreact0.1487best
#2 solid0.2281+53.4%
#3 solid-v20.2578+73.37%

text binding update 1kms

10 entries

Interactivity

Updates one reactive text value that is bound to 1,000 text nodes.

#1 solid0.2758best
#2 solid-v20.3044+10.37%
#3 mreact0.3158+14.5%
#4 svelte0.7543+173.5%
#5 angular0.7852+184.7%
#6 react0.919+233.21%
#7 mreact react-compat1.1597+320.49%
#8 marko1.8068+555.11%
#9 qwik2.3748+761.06%
#10 vue3.6745+1232.31%

computed fan-out 1kms

10 entries

Interactivity

Updates one source value that fans out through a derived value into 1,000 displayed text nodes.

#1 solid0.267best
#2 mreact0.2906+8.84%
#3 solid-v20.3132+17.3%
#4 svelte0.7514+181.42%
#5 react0.8967+235.84%
#6 angular0.9282+247.64%
#7 mreact react-compat1.1029+313.07%
#8 marko1.883+605.24%
#9 qwik2.4199+806.33%
#10 vue3.3684+1161.57%

computed fan-in 1kms

10 entries

Interactivity

Updates the inputs feeding one aggregate and validates one derived aggregate text output. Caveat: this is not a direct cross-framework source-write comparison because mreact, Solid, and Solid v2 update 1,000 fine-grained sources, while React, Marko, and Qwik update one array/props payload.

#1 angular0.0222best
#2 svelte0.0354+59.46%
#3 marko0.0424+90.99%
#4 qwik0.069+210.81%
#5 vue0.0737+231.98%
#6 solid-v20.076+242.34%
#7 react0.0924+316.22%
#8 mreact0.0969+336.49%
#9 mreact react-compat0.1226+452.25%
#10 solid0.1579+611.26%

source write 1kms

3 entries

Interactivity

Updates 1,000 fine-grained source values without subscribers, derived values, DOM writes, or framework-level re-render work, then validates the final source values. Frameworks without an equivalent source primitive report this case as unsupported.

#1 mreact0.0102best
#2 solid0.0118+15.69%
#3 solid-v20.0505+395.1%