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.

Measuring route delivery

A route's imports in .mreact/client/manifest.json lists its direct static imports. A shared chunk can import more chunks, so summing only route.script, route.navigationScript, and route.imports can undercount the JavaScript a browser needs. Follow manifest.chunks[].imports transitively and count each file once. Include navigation's dependencies when budgeting navigation startup, including on a server-rendered route without a client entry. Keep unfetched dynamic imports separate; measure their static dependencies when an interaction actually loads them.

This Node script measures a JavaScript budget for the home route including navigation startup. Run it from the application directory after a production build. It uses Brotli quality 11 for each asset, so the result is a compression estimate rather than observed CDN transfer bytes.

import { readFile } from "node:fs/promises";
import { join } from "node:path";
import { brotliCompressSync, constants } from "node:zlib";

const clientDir = ".mreact/client";
const manifest = JSON.parse(await readFile(join(clientDir, "manifest.json"), "utf8"));
if (!Array.isArray(manifest.chunks)) {
  throw new Error("This manifest lacks a chunk graph; inspect emitted static imports or browser requests instead.");
}
const route = manifest.routes.find((entry) => entry.path === "/");
if (!route) throw new Error("Home route is missing.");
const chunks = new Map(manifest.chunks.map((chunk) => [chunk.file, chunk]));
const files = new Set();
function visit(file) {
  if (!file || files.has(file)) return;
  files.add(file);
  for (const dependency of chunks.get(file)?.imports ?? []) visit(dependency);
}
visit(route.script);
for (const file of route.imports ?? []) visit(file);
if (route.navigation) visit(route.navigationScript);
let rawBytes = 0;
let brotliBytes = 0;
for (const file of files) {
  if (!file.endsWith(".js")) continue;
  const content = await readFile(join(clientDir, file));
  rawBytes += content.byteLength;
  brotliBytes += brotliCompressSync(content, {
    params: { [constants.BROTLI_PARAM_QUALITY]: 11 },
  }).byteLength;
}
console.log({ rawBytes, brotliBytes });

Keep the application source, lockfile, route set, build target, source-map mode, public environment values, and compression settings fixed when comparing framework versions. Preserve each build's assets and manifest separately. For older manifests without chunks, reconstruct the graph from emitted static imports or record browser requests; treating a missing graph as an empty graph gives an incomplete total. A production Sentry or analytics configuration can change the result, so run a release budget with the actual production configuration as well.

Chunk names describe bundler naming choices, not exclusive ownership. A chunk named after a small component can also contain shared runtime code. In particular, mreact-router-compat in a generated virtual-module name is the router's bundler adapter namespace; it does not establish that React compatibility is loaded. Native boundary helpers can contain compatibility checks without importing the React-compatible mounting runtime. Check the reachable implementation and imports before attributing a size increase to compatibility.

Sharing hydration helpers reduces duplication across route entries, but it can change chunk placement and per-file compression. A smaller multi-route session does not guarantee a smaller cold load for every route. Upgrades spanning several releases also include rendering and reactivity fixes, so compare adjacent versions when attributing a regression to a particular optimization. Keep route budgets as explicit application checks instead of relying on a release-wide size claim.

Latest results

Run 2026-10-10/002

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-10-10/002

View run on GitHub

Date
2026-10-10
Commit
207b25e
Node
v24.21.0
CPU
AMD EPYC 7763 64-Core Processor, 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 rows

9 entries

Interactivity

#1 mreact66.7bestScript6.6Paint58.8
#2 marko67.4+1.05%Script7.4Paint59.1
#3 solid67.6+1.35%Script7.3Paint59
#4 svelte70.7+6%Script9.6Paint60.1
#5 react-hooks78.2+17.24%Script17.6Paint58.9
#6 mreact-react-compat79.2+18.74%Script17.9Paint59.8
#7 vue79.5+19.19%Script17.8Paint60.3
#8 mreact-react-compat-vdom92.8+39.13%Script31.8Paint60.5
#9 angular-cf95.2+42.73%Script17.7Paint61

replace all rows

9 entries

Interactivity

#1 mreact71.4bestScript11.3Paint59
#2 marko75+5.04%Script14.9Paint58.8
#3 solid75.5+5.74%Script14.8Paint59.1
#4 svelte77.6+8.68%Script17.1Paint59.2
#5 vue84.5+18.35%Script24.3Paint57.4
#6 mreact-react-compat88.9+24.51%Script27.8Paint59.2
#7 react-hooks92.3+29.27%Script31.8Paint60
#8 mreact-react-compat-vdom102.3+43.28%Script42.4Paint59.9
#9 angular-cf111.1+55.6%Script33.3Paint62.3

partial update

9 entries

SSR

#1 angular-cf39.4bestScript3.5Paint35.5
#2 marko44.3+12.44%Script3.9Paint37.1
#3 mreact45.1+14.47%Script3.7Paint37.5
#4 solid45.3+14.97%Script3.3Paint38.5
#5 vue48.6+23.35%Script5.8Paint39.2
#6 svelte49.1+24.62%Script4.6Paint40.3
#7 mreact-react-compat54+37.06%Script7.4Paint42.1
#8 react-hooks55.8+41.62%Script12.1Paint41
#9 mreact-react-compat-vdom70.8+79.7%Script26.5Paint38

select row

9 entries

Interactivity

#1 mreact8.9bestScript1.1Paint6.2
#2 vue9.4+5.62%Script2.4Paint6
#3 marko9.5+6.74%Script1.4Paint6.4
#4 solid9.9+11.24%Script1.9Paint6.5
#5 mreact-react-compat11.5+29.21%Script3.9Paint6.4
#6 svelte13.5+51.69%Script5.6Paint6.4
#7 angular-cf14.1+58.43%Script4.3Paint8.4
#8 react-hooks14.2+59.55%Script6Paint6.7
#9 mreact-react-compat-vdom15.6+75.28%Script7.5Paint6.6

swap rows

9 entries

Interactivity

#1 angular-cf44.7bestScript2.5Paint41.3
#2 marko45.3+1.34%Script2.7Paint39.2
#3 mreact47.1+5.37%Script2.1Paint41.6
#4 mreact-react-compat48.1+7.61%Script4.2Paint40
#4 vue48.1+7.61%Script2.9Paint41.6
#6 solid49.3+10.29%Script2Paint43
#7 svelte49.7+11.19%Script3.6Paint42.2
#8 mreact-react-compat-vdom67.2+50.34%Script19.6Paint43.9
#9 react-hooks346.2+674.5%Script54.6Paint282.4

remove row

9 entries

Interactivity

#1 angular-cf31.7bestScript1.5Paint29.1
#2 solid32.8+3.47%Script0.9Paint30
#3 mreact34+7.26%Script1.2Paint31.2
#4 marko34.9+10.09%Script1.4Paint31.6
#5 mreact-react-compat35.4+11.67%Script1.8Paint31.9
#6 svelte35.7+12.62%Script1.5Paint32.2
#7 react-hooks36.1+13.88%Script2.8Paint31.2
#8 vue39+23.03%Script4.8Paint32.2
#9 mreact-react-compat-vdom40.4+27.44%Script5.4Paint32.2

create many rows

9 entries

Interactivity

#1 marko748.1bestScript76.2Paint664.9
#2 solid751.9+0.51%Script68.1Paint675.4
#3 mreact754.8+0.9%Script64.9Paint680.1
#4 svelte776.1+3.74%Script85.2Paint679.3
#5 mreact-react-compat863.4+15.41%Script153Paint702.4
#5 vue863.4+15.41%Script155Paint702.6
#7 angular-cf977+30.6%Script195.1Paint700.2
#8 mreact-react-compat-vdom984+31.53%Script286.3Paint689.1
#9 react-hooks1189.5+59%Script467Paint714.5

append rows to large table

9 entries

Interactivity

#1 solid79bestScript8.6Paint68.9
#2 svelte79.8+1.01%Script9.2Paint69.6
#3 mreact80.8+2.28%Script7.2Paint71.8
#4 marko83.8+6.08%Script9.6Paint72.4
#5 vue84.2+6.58%Script15.3Paint67.3
#6 react-hooks89.5+13.29%Script19.3Paint68.9
#7 mreact-react-compat90.1+14.05%Script18Paint70.3
#8 angular-cf104.6+32.41%Script17.9Paint72.1
#9 mreact-react-compat-vdom109.1+38.1%Script38.7Paint68.8

clear rows

9 entries

Interactivity

#1 marko27.4bestScript23.7Paint3
#2 mreact28.5+4.01%Script24.6Paint2.6
#3 solid31.9+16.42%Script28.4Paint2.9
#4 svelte34.3+25.18%Script30.9Paint3.4
#5 mreact-react-compat-vdom38.6+40.88%Script34.9Paint2.8
#6 mreact-react-compat41.5+51.46%Script37.5Paint2.7
#7 vue46.9+71.17%Script42.8Paint3.4
#8 react-hooks51.1+86.5%Script47.1Paint2.8
#9 angular-cf56.1+104.74%Script52.5Paint3.3

ready memory

9 entries

Memory

#1 marko1best
#2 solid1.1+5.33%
#2 mreact1.1+9.26%
#4 svelte1.2+13.77%
#5 vue1.3+26.23%
#5 mreact-react-compat-vdom1.3+30.82%
#7 mreact-react-compat1.4+38%
#8 react-hooks1.7+61.36%
#9 angular-cf2+98.02%

run memory

9 entries

Memory

#1 marko2.7best
#1 mreact2.7+0.13%
#3 solid3.2+16.09%
#4 svelte3.5+27.98%
#5 vue4.4+62.03%
#6 mreact-react-compat4.7+70.46%
#7 mreact-react-compat-vdom4.9+80.17%
#8 react-hooks5+83.06%
#9 angular-cf5.1+85.92%

repeated clear memory

9 entries

Memory

#1 solid1.3best
#2 mreact1.4+6.65%
#2 marko1.4+7.33%
#4 svelte1.5+16.78%
#5 vue1.6+28.81%
#6 mreact-react-compat1.8+44.39%
#7 react-hooks2.5+97.34%
#8 mreact-react-compat-vdom2.6+104.31%
#9 angular-cf2.8+117.01%

total byte weight

9 entries

SSR

#1 solid4.5best
#2 marko4.6+2.22%
#3 mreact10.5+133.33%
#4 svelte11.6+157.78%
#5 vue23.7+426.67%
#6 mreact-react-compat-vdom36.3+706.67%
#7 mreact-react-compat43.8+873.33%
#8 angular-cf45.5+911.11%
#9 react-hooks58.7+1204.44%

Router benchmarks

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

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

11 entries

SizeClientProduction

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

#1 marko-run0
#1 svelte-kit0
#1 mreact-app-router0
#1 mreact-app-router+mreact react-compat0
#1 mreact-app-router+log enabled0
#6 solid-start20211
#7 qwik-city25534
#8 tanstack-start-solid58912
#9 nuxt65524
#10 tanstack-start105765
#11 next-app-router145590

app client bundle gzip bytes (interactive page)gzip bytes

11 entries

SizeClientProduction

Compatibility alias for gzip-compressed client JavaScript fetched by the minimal button-and-state interactive route after idle settle. mreact variant spread: +201.47%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run1335best
#2 mreact-app-router17059+1177.83%
#2 mreact-app-router+log enabled17059+1177.83%
#4 solid-start19242+1341.35%
#5 svelte-kit31457+2256.33%
#6 qwik-city35081+2527.79%
#7 mreact-app-router+mreact react-compat51427+3752.21%
#8 tanstack-start-solid57065+4174.53%
#9 nuxt68092+5000.52%
#10 tanstack-start104142+7700.9%
#11 next-app-router149264+11080.82%

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

11 entries

SizeClientProduction

Measures the same interactive route while opting out of optional client navigation runtime where the framework supports it. mreact variant spread: +588.97%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run1335best
#2 mreact-app-router5921+343.52%
#2 mreact-app-router+log enabled5921+343.52%
#4 solid-start19242+1341.35%
#5 svelte-kit31457+2256.33%
#6 qwik-city35081+2527.79%
#7 mreact-app-router+mreact react-compat40794+2955.73%
#8 tanstack-start-solid57065+4174.53%
#9 nuxt68097+5000.9%
#10 tanstack-start104142+7700.9%
#11 next-app-router149264+11080.82%

app render 1000 nodesops/sec

11 entries

SSRServerProduction

Renders a production app route that emits 1,000 simple text spans. mreact variant spread: +1.99%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat1126best
#2 mreact-app-router+log enabled1124-0.18%
#3 mreact-app-router1104-1.95%
#4 nuxt878-22.02%
#5 marko-run824-26.82%
#6 tanstack-start757-32.77%
#7 svelte-kit737-34.55%
#8 qwik-city686-39.08%
#9 solid-start418-62.88%
#10 tanstack-start-solid322-71.4%
#11 next-app-router86-92.36%

app streaming 1000 nodesops/sec

11 entries

SSRServerProduction

Streams a production app route with 1,000 simple text spans and validates the complete response body. mreact variant spread: +5.1%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat1072best
#2 mreact-app-router+log enabled1047-2.33%
#3 marko-run1030-3.92%
#4 mreact-app-router1020-4.85%
#5 nuxt998-6.9%
#6 svelte-kit823-23.23%
#7 tanstack-start757-29.38%
#8 qwik-city591-44.87%
#9 solid-start388-63.81%
#10 tanstack-start-solid329-69.31%
#11 next-app-router80-92.54%

app streaming first byte 1000 nodesms

11 entries

SSRServerProduction

Measures elapsed time until fetch resolves response headers for the real streaming route. mreact variant spread: +20.79%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat1.103best
#2 mreact-app-router+log enabled1.2032+9.08%
#3 marko-run1.2529+13.59%
#4 mreact-app-router1.3323+20.79%
#5 qwik-city1.3974+26.69%
#6 solid-start2.3795+115.73%
#7 next-app-router3.399+208.16%
#8 nuxt51.8571+4601.46%
#9 tanstack-start52.2239+4634.71%
#10 svelte-kit52.4898+4658.82%
#11 tanstack-start-solid54.3486+4827.34%

app streaming first chunk 1000 nodesms

11 entries

SSRServerProduction

Measures elapsed time until the first response body chunk arrives for the real streaming route. mreact variant spread: +24.2%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat1.1131best
#2 mreact-app-router+log enabled1.3071+17.43%
#3 marko-run1.3674+22.85%
#4 mreact-app-router1.3825+24.2%
#5 qwik-city1.4446+29.78%
#6 solid-start2.4714+122.03%
#7 next-app-router3.5202+216.25%
#8 nuxt51.8109+4554.65%
#9 svelte-kit52.4803+4614.79%
#10 tanstack-start52.5015+4616.69%
#11 tanstack-start-solid54.5276+4798.72%

app streaming full body 1000 nodesms

11 entries

SSRServerProduction

Measures elapsed time until the complete real streaming response body is consumed and validated. mreact variant spread: +0.32%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled50.6122best
#2 mreact-app-router+mreact react-compat50.7131+0.2%
#3 mreact-app-router50.7718+0.32%
#4 nuxt51.8175+2.38%
#5 marko-run52.0401+2.82%
#6 tanstack-start52.1441+3.03%
#7 solid-start52.3555+3.44%
#8 qwik-city52.6036+3.93%
#9 svelte-kit52.6509+4.03%
#10 tanstack-start-solid54.4084+7.5%
#11 next-app-router59.5774+17.71%

app real streaming 1000 nodes (async 50ms)ms

11 entries

SSRServerProduction

Measures complete response latency for a route whose body waits on a 50 ms async boundary. mreact variant spread: +2.02%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled51.0713best
#2 mreact-app-router+mreact react-compat51.5338+0.91%
#3 solid-start51.6478+1.13%
#4 marko-run51.8541+1.53%
#5 nuxt51.9636+1.75%
#6 mreact-app-router52.1008+2.02%
#7 tanstack-start52.3981+2.6%
#8 qwik-city52.7408+3.27%
#9 svelte-kit52.9615+3.7%
#10 tanstack-start-solid54.4978+6.71%
#11 next-app-router60.2089+17.89%

app parallel async boundaries 2x50msms

11 entries

SSRServerProduction

Measures complete response latency for two sibling 50 ms async boundaries; parallel renderers stay near one boundary. mreact variant spread: +0.13%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled50.9805best
#2 mreact-app-router50.9906+0.02%
#3 mreact-app-router+mreact react-compat51.0485+0.13%
#4 solid-start51.0822+0.2%
#5 svelte-kit51.5166+1.05%
#6 marko-run51.6258+1.27%
#7 nuxt51.7224+1.46%
#8 tanstack-start51.7386+1.49%
#9 qwik-city52.0197+2.04%
#10 tanstack-start-solid53.165+4.28%
#11 next-app-router53.2166+4.39%

app static cached route 1000 nodesops/sec

6 entries

SSRServerProduction

Renders a static-cacheable app route with 1,000 simple text spans after the production server has warmed it. mreact variant spread: +2.75%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router1083best
#2 mreact-app-router+mreact react-compat1057-2.4%
#3 mreact-app-router+log enabled1054-2.68%
#4 nuxt1022-5.63%
#5 svelte-kit814-24.84%
#6 next-app-router382-64.73%

app dynamic-attr grid 200 cellsops/sec

11 entries

SSRServerProduction

Renders 200 cells with many dynamic escaped attributes, inline style values, and text content. mreact variant spread: +1.86%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat930best
#2 mreact-app-router+log enabled922-0.86%
#3 mreact-app-router913-1.83%
#4 nuxt798-14.19%
#5 marko-run603-35.16%
#6 svelte-kit569-38.82%
#7 tanstack-start524-43.66%
#8 qwik-city494-46.88%
#9 solid-start439-52.8%
#10 tanstack-start-solid384-58.71%
#11 next-app-router103-88.92%

app dynamic route params dataops/sec

11 entries

RoutingServerProduction

Renders a dynamic route that combines route parameters with server data before producing HTML. mreact variant spread: +2.84%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router869best
#2 mreact-app-router+log enabled866-0.35%
#3 mreact-app-router+mreact react-compat845-2.76%
#4 nuxt768-11.62%
#5 marko-run623-28.31%
#6 svelte-kit565-34.98%
#7 tanstack-start485-44.19%
#8 qwik-city466-46.38%
#9 solid-start444-48.91%
#10 tanstack-start-solid378-56.5%
#11 next-app-router102-88.26%

app HTTP v2 burst throughput (max 100 in-flight)ops/sec

11 entries

SSRServerProduction

Isolated HTTP/1.1 burst load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run1288.7809325788949best
#2 mreact-app-router+log enabled1029.9805661721807-20.08%
#3 svelte-kit1007.305828001563-21.84%
#4 mreact-app-router864.2509645137992-32.94%
#5 mreact-app-router+mreact react-compat832.7427313696776-35.39%
#6 nuxt674.7021898269212-47.65%
#7 tanstack-start669.2523095796815-48.07%
#8 qwik-city665.278602778685-48.38%
#9 solid-start591.0434790171482-54.14%
#10 tanstack-start-solid433.20346810306944-66.39%
#11 next-app-router108.17784334677259-91.61%

app HTTP v2 burst p50 latency (max 100 in-flight)ms

11 entries

SSRServerProduction

Isolated HTTP/1.1 burst load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run58.702901999999995best
#2 mreact-app-router+log enabled64.65793200000002+10.14%
#3 svelte-kit81.85975900000003+39.45%
#4 mreact-app-router+mreact react-compat96.99139399999999+65.22%
#5 mreact-app-router103.62207900000001+76.52%
#6 nuxt110.20832299999995+87.74%
#7 tanstack-start120.06956299999999+104.54%
#8 solid-start126.496216+115.49%
#9 qwik-city130.257418+121.89%
#10 tanstack-start-solid164.963841+181.01%
#11 next-app-router887.739646+1412.26%

app HTTP v2 burst p95 latency (max 100 in-flight)ms

11 entries

SSRServerProduction

Isolated HTTP/1.1 burst load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run81.07607699999998best
#2 svelte-kit114.223885+40.88%
#3 mreact-app-router+log enabled118.53355499999999+46.2%
#4 mreact-app-router124.98564199999998+54.16%
#5 mreact-app-router+mreact react-compat135.47389800000002+67.09%
#6 tanstack-start165.984038+104.73%
#7 nuxt186.22197400000002+129.69%
#8 qwik-city192.78992+137.79%
#9 solid-start245.12695000000002+202.34%
#10 tanstack-start-solid323.403604+298.89%
#11 next-app-router967.4705959999999+1093.29%

app HTTP v2 burst p99 latency (max 100 in-flight)ms

11 entries

SSRServerProduction

Isolated HTTP/1.1 burst load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run85.03967799999998best
#2 mreact-app-router+log enabled120.879286+42.14%
#3 mreact-app-router126.26091000000001+48.47%
#4 svelte-kit137.876419+62.13%
#5 mreact-app-router+mreact react-compat137.899031+62.16%
#6 tanstack-start176.01470799999998+106.98%
#7 nuxt190.28669000000002+123.76%
#8 qwik-city203.952174+139.83%
#9 solid-start248.91800400000002+192.71%
#10 tanstack-start-solid347.176468+308.25%
#11 next-app-router970.808566+1041.59%

app HTTP v2 burst server RSS delta (max 100 in-flight)bytes

9 entries

MemoryServerProduction

Isolated HTTP/1.1 burst load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 mreact-app-router+log enabled4096best
#2 tanstack-start16384+300%
#3 qwik-city2519040+61400%
#4 marko-run6901760+168400%
#5 mreact-app-router8777728+214200%
#6 mreact-app-router+mreact react-compat15994880+390400%
#7 nuxt30334976+740500%
#8 solid-start37187584+907800%
#9 tanstack-start-solid72138752+1761100%

app HTTP v2 steady throughput (max 100 in-flight)ops/sec

11 entries

SSRServerProduction

Isolated HTTP/1.1 steady load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run3948.852246870845best
#2 mreact-app-router+log enabled1911.6076940691037-51.59%
#3 svelte-kit1911.062392319186-51.6%
#4 mreact-app-router+mreact react-compat1908.0460696063471-51.68%
#5 mreact-app-router1893.7623314805737-52.04%
#6 nuxt1196.8032052817537-69.69%
#7 tanstack-start1076.0736604069773-72.75%
#8 qwik-city967.6045991946669-75.5%
#9 solid-start791.5888621619928-79.95%
#10 tanstack-start-solid555.256044343474-85.94%
#11 next-app-router115.93611955907073-97.06%

app HTTP v2 steady p50 latency (max 100 in-flight)ms

11 entries

SSRServerProduction

Isolated HTTP/1.1 steady load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run24.603522999999768best
#2 mreact-app-router+mreact react-compat50.98043099999995+107.21%
#3 mreact-app-router+log enabled51.13206799999898+107.82%
#4 mreact-app-router51.44267000000036+109.09%
#5 svelte-kit53.97644600000058+119.39%
#6 nuxt89.83305399999972+265.12%
#7 tanstack-start90.9697299999998+269.74%
#8 qwik-city100.38572000000022+308.01%
#9 solid-start122.52920199999971+398.01%
#10 tanstack-start-solid170.4652299999998+592.85%
#11 next-app-router862.8514670000004+3407.02%

app HTTP v2 steady p95 latency (max 100 in-flight)ms

11 entries

SSRServerProduction

Isolated HTTP/1.1 steady load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run29.408652000000075best
#2 mreact-app-router+log enabled57.0928329999997+94.14%
#3 mreact-app-router+mreact react-compat58.40862300000026+98.61%
#4 mreact-app-router60.351487999998426+105.22%
#5 svelte-kit64.2642190000006+118.52%
#6 tanstack-start102.0674390000022+247.07%
#7 qwik-city111.97927200000049+280.77%
#8 nuxt115.00872299999901+291.07%
#9 solid-start147.47026299999925+401.45%
#10 tanstack-start-solid219.07218199999988+644.92%
#11 next-app-router904.1747029999988+2974.52%

app HTTP v2 steady p99 latency (max 100 in-flight)ms

11 entries

SSRServerProduction

Isolated HTTP/1.1 steady load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run32.96062400000119best
#2 mreact-app-router+log enabled75.94221300000027+130.4%
#3 svelte-kit76.19999699999971+131.18%
#4 mreact-app-router77.0321440000007+133.71%
#5 mreact-app-router+mreact react-compat88.03576299999986+167.09%
#6 tanstack-start112.94995400000153+242.68%
#7 qwik-city120.17468899999949+264.6%
#8 nuxt128.60310000000027+290.17%
#9 solid-start242.9926319999995+637.22%
#10 tanstack-start-solid366.4076810000006+1011.65%
#11 next-app-router906.7730630000005+2651.08%

app HTTP v2 steady server RSS delta (max 100 in-flight)bytes

10 entries

MemoryServerProduction

Isolated HTTP/1.1 steady load. All five metrics derive from the same trials; workload and connection metadata are retained in JSON. Methodology v2 uses separate orchestrator, load generator and production server processes. All five metrics share the same trials. RSS is a single server PID's before/after delta, not a peak or process-tree total; negative samples remain in JSON but are excluded from RSS rankings. Route/cache conditions still differ across adapters (mreact uses /static-page with its route cache); consult httpTrials before comparing frameworks. These measurements are not directly comparable to legacy concurrent probes. Steady windows share one warmed connection pool; burst trials start fresh pools, not cold servers.

#1 marko-run12288best
#2 qwik-city3284992+26633.33%
#3 nuxt4317184+35033.33%
#4 tanstack-start-solid4874240+39566.67%
#5 tanstack-start10076160+81900%
#6 svelte-kit11673600+94900%
#7 solid-start26497024+215533.33%
#8 mreact-app-router+mreact react-compat32677888+265833.33%
#9 mreact-app-router45174784+367533.33%
#10 mreact-app-router+log enabled55033856+447766.67%

app browser v2 domcontentloaded initial content observedms

10 entries

InteractivityBrowserServerProduction

Verified initial content observed in a fresh domcontentloaded trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +18.67%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run44.5best
#2 mreact-app-router52.5+17.98%
#2 mreact-app-router+log enabled52.5+17.98%
#4 solid-start55.30000000074506+24.27%
#5 mreact-app-router+mreact react-compat62.30000000074506+40%
#6 svelte-kit63.200000000186265+42.02%
#7 qwik-city63.799999999813735+43.37%
#8 nuxt77.29999999981374+73.71%
#9 tanstack-start89+100%
#10 next-app-router118.40000000037253+166.07%

app browser v2 domcontentloaded navigation to first verified updatems

10 entries

NavigationClientBrowserServer

Verified navigation to first verified update in a fresh domcontentloaded trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +12.38%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run94best
#2 mreact-app-router102.59999999962747+9.15%
#3 solid-start107.20000000018626+14.04%
#4 mreact-app-router+log enabled108+14.89%
#5 mreact-app-router+mreact react-compat115.29999999981374+22.66%
#6 nuxt117.79999999981374+25.32%
#7 svelte-kit121.59999999962747+29.36%
#8 qwik-city124+31.91%
#9 tanstack-start136+44.68%
#10 next-app-router195.70000000018626+108.19%

app browser v2 domcontentloaded first click E2Ems

10 entries

InteractivityBrowserServerProduction

Verified first click E2E in a fresh domcontentloaded trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +7.71%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 nuxt19.699999999254942best
#2 tanstack-start26.899999999441206+36.55%
#3 marko-run31.700000000186265+60.91%
#4 mreact-app-router35+77.66%
#5 mreact-app-router+log enabled36.200000000186265+83.76%
#6 mreact-app-router+mreact react-compat37.700000000186265+91.37%
#7 solid-start38.299999999813735+94.42%
#8 qwik-city43+118.27%
#8 next-app-router43+118.27%
#10 svelte-kit43.09999999962747+118.78%

app browser v2 domcontentloaded first click event-to-DOMms

10 entries

InteractivityBrowserServerProduction

Verified first click event-to-DOM in a fresh domcontentloaded trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +242.86%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run0.39999999944120646best
#1 solid-start0.399999999441206460%
#3 nuxt0.400000000372529030%
#4 svelte-kit0.5+25%
#5 mreact-app-router0.7000000001862645+75%
#6 mreact-app-router+log enabled0.7999999998137355+100%
#7 next-app-router1.099999999627471+175%
#8 tanstack-start1.2000000001862645+200%
#9 mreact-app-router+mreact react-compat2.3999999994412065+500%
#10 qwik-city13.700000000186265+3325%

app browser v2 networkidle first click E2Ems

10 entries

InteractivityBrowserServerProduction

Verified first click E2E in a fresh networkidle trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +7.46%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run16.09999999962747best
#2 nuxt17.90000000037253+11.18%
#3 tanstack-start20.59999999962747+27.95%
#4 svelte-kit21.600000000558794+34.16%
#4 solid-start21.600000000558794+34.16%
#6 next-app-router25.799999999813735+60.25%
#7 mreact-app-router+log enabled26.799999999813735+66.46%
#8 mreact-app-router27.700000000186265+72.05%
#9 mreact-app-router+mreact react-compat28.799999999813735+78.88%
#10 qwik-city37.799999999813735+134.78%

app browser v2 networkidle first click event-to-DOMms

10 entries

InteractivityBrowserServerProduction

Verified first click event-to-DOM in a fresh networkidle trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +200%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run0.2999999998137355best
#1 nuxt0.29999999981373550%
#1 svelte-kit0.29999999981373550%
#1 solid-start0.29999999981373550%
#5 mreact-app-router+log enabled0.599999999627471+100%
#6 mreact-app-router0.6000000005587935+100%
#7 tanstack-start0.8999999994412065+200%
#8 next-app-router1.099999999627471+266.67%
#9 mreact-app-router+mreact react-compat1.800000000745058+500%
#10 qwik-city14.5+4733.33%

app browser v2 networkidle second click E2Ems

10 entries

InteractivityBrowserServerProduction

Verified second click E2E in a fresh networkidle trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +62.6%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled26.200000000186265best
#2 svelte-kit26.299999999813735+0.38%
#3 marko-run26.5+1.15%
#4 solid-start26.90000000037253+2.67%
#5 mreact-app-router28.200000000186265+7.63%
#6 nuxt41.09999999962747+56.87%
#7 tanstack-start42.09999999962747+60.69%
#8 next-app-router42.200000000186265+61.07%
#9 mreact-app-router+mreact react-compat42.59999999962747+62.6%
#10 qwik-city61.59999999962747+135.11%

app browser v2 networkidle second click event-to-DOMms

10 entries

InteractivityBrowserServerProduction

Verified second click event-to-DOM in a fresh networkidle trial. SSR content is checked separately with JavaScript disabled. E2E includes Playwright; event-to-DOM includes observer delivery, not paint or INP. Browser methodology v2 verifies SSR separately with JavaScript disabled and requires two working counter interactions. Related metrics share trials and IDs in browserTrials. E2E includes Playwright automation; event-to-DOM ends at MutationObserver delivery, not paint or INP. Network-idle profiles include the explicit quiet-period wait before interaction. These measurements are not directly comparable to legacy browser probes. mreact variant spread: +400%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run0.09999999962747097best
#1 mreact-app-router+log enabled0.099999999627470970%
#3 svelte-kit0.100000000558793540%
#3 mreact-app-router0.100000000558793540%
#5 nuxt0.19999999925494194+100%
#5 solid-start0.19999999925494194+100%
#7 next-app-router0.40000000037252903+300%
#8 tanstack-start0.5+400%
#8 mreact-app-router+mreact react-compat0.5+400%
#10 qwik-city14.5+14400%

app loader client navigation route-to-routems

7 entries

NavigationClientProduction

Measures browser client navigation to a route with loader data, covering data-bearing SPA transitions. mreact variant spread: +8.01%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled28.7best
#2 mreact-app-router30.5+6.27%
#3 mreact-app-router+mreact react-compat31+8.01%
#4 solid-start42.6+48.43%
#5 tanstack-start53+84.67%
#6 next-app-router62.1+116.38%
#7 qwik-city97.9+241.11%

app client navigation back-forward restorems

9 entries

NavigationClientProduction

Measures browser back-forward restoration after SPA navigation so history snapshot regressions are visible. Includes Playwright navigation commands and locator waits around both traversals. The result includes automation scheduling and is not a direct measure of browser DOM work. mreact variant spread: +134.39%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 solid-start9best
#2 svelte-kit9.4+4.44%
#3 next-app-router10.7+18.89%
#4 tanstack-start12.1+34.44%
#5 mreact-app-router+mreact react-compat15.7+74.44%
#6 nuxt32+255.56%
#7 mreact-app-router+log enabled36.1+301.11%
#8 mreact-app-router36.8+308.89%
#9 qwik-city108.4+1104.44%

app client navigation back-forward first visible DOMms

9 entries

NavigationClientProduction

Measures popstate-to-first-visible-route-DOM for back and forward inside the browser; excludes Playwright command and locator waits, later state updates, and paint. The sum of back and forward popstate-to-first-visible-route-DOM intervals measured by MutationObserver inside the browser. The same first-visible count 0 or 1 rule applies to every adapter; later state updates are excluded. It includes asynchronous route fetching after popstate but excludes Playwright command and locator waits; it is not paint or INP and is not directly comparable to the Playwright wall-time case. mreact variant spread: +7.23%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 solid-start1.5best
#2 svelte-kit2.6+73.33%
#3 next-app-router3.6+140%
#4 tanstack-start5.3+253.33%
#5 mreact-app-router+mreact react-compat8.3+453.33%
#6 mreact-app-router+log enabled8.4+460%
#7 mreact-app-router8.9+493.33%
#8 nuxt16.3+986.67%
#9 qwik-city62.4+4060%

app client navigation route-to-routems

9 entries

NavigationClientProduction

Measures route-to-route client navigation latency in a real browser when the adapter provides a browser probe. mreact variant spread: +2.04%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat34.3best
#2 mreact-app-router35+2.04%
#2 mreact-app-router+log enabled35+2.04%
#4 svelte-kit51.7+50.73%
#5 solid-start54.4+58.6%
#6 tanstack-start56.5+64.72%
#7 next-app-router58+69.1%
#8 nuxt104.4+204.37%
#9 qwik-city116.2+238.78%

app SSR HTML gzip bytes 1000 nodesgzip bytes

11 entries

SizeServerProduction

Measures gzip-compressed HTML payload bytes for the 1,000-node SSR route, complementing client bundle size cases. mreact variant spread: 0%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run2184best
#2 mreact-app-router2301+5.36%
#2 mreact-app-router+mreact react-compat2301+5.36%
#2 mreact-app-router+log enabled2301+5.36%
#5 svelte-kit2749+25.87%
#6 nuxt2894+32.51%
#7 tanstack-start3514+60.9%
#8 qwik-city6105+179.53%
#9 solid-start9417+331.18%
#10 tanstack-start-solid9782+347.89%
#11 next-app-router14922+583.24%

app client bundle gzip bytes before interaction (interactive page)gzip bytes

11 entries

SizeClientBrowserProduction

Measures gzip-compressed client JavaScript completed before the minimal interactive route responds to its first click. mreact variant spread: +201.47%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run1335best
#2 mreact-app-router17059+1177.83%
#2 mreact-app-router+log enabled17059+1177.83%
#4 solid-start19242+1341.35%
#5 qwik-city24439+1730.64%
#6 svelte-kit31457+2256.33%
#7 mreact-app-router+mreact react-compat51427+3752.21%
#8 tanstack-start-solid57065+4174.53%
#9 nuxt67903+4986.37%
#10 tanstack-start104142+7700.9%
#11 next-app-router149264+11080.82%

app client bundle gzip bytes after idle settle (interactive page)gzip bytes

11 entries

SizeClientProduction

Measures gzip-compressed client JavaScript fetched by the minimal interactive route after the browser reaches networkidle. mreact variant spread: +201.47%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run1335best
#2 mreact-app-router17059+1177.83%
#2 mreact-app-router+log enabled17059+1177.83%
#4 solid-start19242+1341.35%
#5 svelte-kit31457+2256.33%
#6 qwik-city35081+2527.79%
#7 mreact-app-router+mreact react-compat51427+3752.21%
#8 tanstack-start-solid57065+4174.53%
#9 nuxt68092+5000.52%
#10 tanstack-start104142+7700.9%
#11 next-app-router149264+11080.82%

app client bundle gzip bytes (interactive page, 3 shared routes)gzip bytes

3 entries

SizeClientProduction

Measures a three-route interactive app that shares client route runtime chunks, making per-route glue dedup visible. mreact variant spread: +191.95%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router14578best
#1 mreact-app-router+log enabled145780%
#3 mreact-app-router+mreact react-compat42560+191.95%

app build output gzip bytesgzip bytes

11 entries

SizeServerProduction

Measures gzip-compressed production build output size when the adapter exposes build artifacts. mreact variant spread: +0.04%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 marko-run78323best
#2 mreact-app-router78554+0.29%
#3 mreact-app-router+log enabled78581+0.33%
#4 mreact-app-router+mreact react-compat78586+0.34%
#5 tanstack-start-solid159994+104.27%
#6 tanstack-start167831+114.28%
#7 svelte-kit176756+125.68%
#8 solid-start180025+129.85%
#9 qwik-city288585+268.45%
#10 next-app-router419499+435.6%
#11 nuxt550434+602.77%

app 100 islands verified interaction E2Ems

3 entries

InteractivityClientBrowserProduction

Loads 100 islands and verifies every independent 0-to-1 update with ordinary Playwright clicks. Includes navigation and all 100 operations; not hydration time. This section currently compares mreact app-router variants only; it is not a cross-framework ranking. Includes navigation and sequential Playwright interactions with every island, checking independent state after each click. This is functional end-to-end duration, not hydration time. mreact variant spread: +1.54%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router3472.8819best
#2 mreact-app-router+log enabled3473.1793+0.01%
#3 mreact-app-router+mreact react-compat3526.3738+1.54%

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. mreact variant spread: +15.97%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat3.5945best
#2 mreact-app-router4.0802+13.51%
#3 mreact-app-router+log enabled4.1685+15.97%

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. mreact variant spread: +387.21%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled31.3482best
#2 mreact-app-router32.0491+2.24%
#3 mreact-app-router+mreact react-compat152.7325+387.21%

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. mreact variant spread: +408.42%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled28.0355best
#2 mreact-app-router28.9614+3.3%
#3 mreact-app-router+mreact react-compat142.5374+408.42%

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. mreact variant spread: +132.92%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router9.9312best
#2 mreact-app-router+mreact react-compat13.3139+34.06%
#3 mreact-app-router+log enabled23.1314+132.92%

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. mreact variant spread: +3.21%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router504.8472best
#2 mreact-app-router+log enabled519.3214+2.87%
#3 mreact-app-router+mreact react-compat521.0778+3.21%

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. mreact variant spread: +35.73%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router12978.2944best
#2 mreact-app-router+mreact react-compat15117.5147+16.48%
#3 mreact-app-router+log enabled17615.2039+35.73%

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. mreact variant spread: +6.95%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router638746624best
#2 mreact-app-router+mreact react-compat667906048+4.57%
#3 mreact-app-router+log enabled683155456+6.95%

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. mreact variant spread: +3.82%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat43.3164best
#2 mreact-app-router+log enabled43.7946+1.1%
#3 mreact-app-router44.9709+3.82%

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. mreact variant spread: +32.42%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled35.875best
#2 mreact-app-router35.877+0.01%
#3 mreact-app-router+mreact react-compat47.5074+32.42%

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. mreact variant spread: +29.74%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+log enabled3.3435best
#2 mreact-app-router3.4082+1.94%
#3 mreact-app-router+mreact react-compat4.3377+29.74%

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. mreact variant spread: +2.37%. This includes implementation and configuration differences; it is not measurement noise or a statistical significance threshold.

#1 mreact-app-router+mreact react-compat337.1715best
#2 mreact-app-router+log enabled339.5698+0.71%
#3 mreact-app-router345.1771+2.37%

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 mreact3.9517best
#2 solid-v24.0036+1.31%
#3 solid4.0897+3.49%
#4 vue4.5987+16.37%
#5 mreact react-compat5.4302+37.41%
#6 react5.5591+40.68%
#7 marko6.9018+74.65%
#8 qwik8.3071+110.22%
#9 angular8.8037+122.78%
#10 svelte38.3226+869.78%

create 1k event targetsms

10 entries

Interactivity

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

#1 mreact10.2932best
#2 solid-v210.3433+0.49%
#3 solid11.3538+10.3%
#4 vue11.4691+11.42%
#5 react11.7319+13.98%
#6 angular12.6788+23.18%
#7 mreact react-compat12.7669+24.03%
#8 qwik13.7615+33.7%
#9 svelte16.5329+60.62%
#10 marko18.7276+81.94%

repeated create update clear memorybytes

10 entries

Memory

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

#1 svelte35864best
#2 mreact48464+35.13%
#3 qwik73888+106.02%
#4 marko79104+120.57%
#5 solid-v288880+147.83%
#6 solid108704+203.1%
#7 mreact react-compat328224+815.19%
#8 vue328488+815.93%
#9 react359952+903.66%
#10 angular377632+952.96%

Primitive reactivity microbenchmarks

primitive.md / 4 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.0865best
#2 solid-v20.1868+115.95%
#3 solid0.1984+129.36%

text binding update 1kms

10 entries

Interactivity

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

#1 solid0.2747best
#2 solid-v20.2962+7.83%
#3 mreact0.3075+11.94%
#4 svelte0.6435+134.26%
#5 react0.6749+145.69%
#6 angular0.6926+152.13%
#7 mreact react-compat0.9996+263.89%
#8 marko1.6245+491.37%
#9 qwik2.0351+640.84%
#10 vue3.2711+1090.79%

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.276best
#2 solid-v20.2907+5.33%
#3 mreact0.3081+11.63%
#4 svelte0.6488+135.07%
#5 angular0.7153+159.17%
#6 react0.7873+185.25%
#7 mreact react-compat1.0537+281.78%
#8 marko1.7506+534.28%
#9 qwik2.1215+668.66%
#10 vue3.2123+1063.88%

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.0106best
#2 solid0.0122+15.09%
#3 solid-v20.0358+237.74%

Primitive browser benchmarks

primitive-browser.md / 4 ranking cards / View source on GitHub

browser create 1k rowsms

8 entries

InteractivityBrowser

Creates 1,000 keyed DOM rows in real Chromium, mirroring the primitive create case without happy-dom.

#1 solid1.86best
#2 mreact3.87+108.06%
#3 mreact react-compat5.35+187.63%
#4 vue6.755+263.17%
#5 qwik7.17+285.48%
#6 react7.185+286.29%
#7 svelte7.815+320.16%
#8 angular8.145+337.9%

browser update every 10th in 10k rowsms

8 entries

InteractivityBrowser

Updates every tenth row in a 10,000-row keyed DOM in real Chromium, exposing real DOM update costs hidden by happy-dom.

#1 mreact2.56best
#2 svelte6.21+142.58%
#3 mreact react-compat7.295+184.96%
#4 angular7.385+188.48%
#5 solid9.425+268.16%
#6 react12.085+372.07%
#7 vue16.47+543.36%
#8 qwik19.145+647.85%

browser select row in 10k rowsms

8 entries

InteractivityBrowser

Toggles selection attributes for one row in a 10,000-row keyed DOM in real Chromium.

#1 mreact0.95best
#2 solid1.025+7.89%
#3 mreact react-compat5.25+452.63%
#4 svelte6.275+560.53%
#5 angular6.65+600%
#6 react12.22+1186.32%
#7 vue13.69+1341.05%
#8 qwik19.3+1931.58%

browser clear 10k rowsms

8 entries

InteractivityBrowser

Clears a 10,000-row keyed DOM in real Chromium to validate happy-dom clear rankings against browser behavior.

#1 mreact2.36best
#2 mreact react-compat5.5+133.05%
#3 solid5.59+136.86%
#4 vue10.735+354.87%
#5 react11.125+371.4%
#6 qwik11.275+377.75%
#7 svelte11.49+386.86%
#8 angular17.04+622.03%