Benchmarks

Benchmark score in milliseconds per operation — lower is better. Every chart is the checked-in baseline from the repo’s own suites: same apps, same hardware, same run. Reproduce them with pnpm bench:all, and see benchmarks/ for what each suite measures.

Every suite at a glance

Start here: each cell is the geometric mean of that suite’s per-operation scores relative to Octane — 1× is Octane, below 1× is faster than Octane. Pick frameworks and a suite for the bar view, or scan the whole grid and re-baseline it to each suite’s fastest framework. The sections below have the full per-operation charts in milliseconds.

frameworks
suite
all suites
suiteOctane (.tsrx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
js-framework2.6×2.5×1.1×1.7×1.1×1.0×
todomvc3.8×4.3×1.8×1.3×1.2×1.5×
chat-stream3.1×3.9×1.2×1.6×1.2×0.90×
js-framework-reorder2.9×6.3×1.7×2.2×1.6×2.1×
dbmon2.0×2.5×2.6×1.3×1.3×1.2×
effectful-list2.4×5.1×0.69×0.86×1.1×0.90×
memo-wall4.9×6.2×0.29×1.0×2.4×0.29×
recursive-context1.6×1.6×1.1×2.2×1.1×1.0×
signal-favoring7.4×6.3×0.76×1.1×0.33×0.40×
portal-swarm1.2×1.4×0.47×1.3×0.82×0.96×
async-waterfall12×9.4×0.96×0.96×0.94×
news1.5×1.2×0.93×0.51×0.49×0.63×
streaming-ssr1.4×1.3×4.5×1.3×
bundle-size1.0×0.62×0.76×0.88×0.84×0.74×
ssr-throughput3.1×2.8×1.9×1.2×1.1×1.1×
geomean2.7×2.9×1.1×1.2×1.0×0.87×

Each cell is that framework’s score relative to Octane (1×), geometric mean across the suite’s operations. Green is faster, red is slower.

FasterSlowerOctane = 1× baseline

Octane vs the field

Octane compiled from .tsrx and .tsx, against React 19 (with a separate React Compiler comparison where available), Preact 10, Solid, Svelte 5, Ripple and Vue Vapor — each framework’s fixture written the way its docs recommend. The ranked chips on each card are that suite’s one-line reading: every framework’s geometric mean across the card’s operations, relative to Octane, fastest first.

js-frameworkkrausest-style table operations over 1,000 rows — create, replace, partial update, select, swap, remove, clear.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 8 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
run2.22.25.77.92.23.82.42.8
replace4.85.09.7135.67.45.25.4
add1.71.74.76.71.83.11.92.0
update0.380.341.11.51.10.720.580.46
select0.120.160.641.10.140.160.100.04
swap0.460.444.60.880.460.800.740.56
remove0.240.180.620.700.160.500.220.22
runlots13141165314241417
clear2022463222252421
nodes_1k1007410074100721007210072101161007410072
elements_1k80518051805180518051805180518050
text_1k20212021202120212021204520232022
comments_1k2.02.00002000
empty_text_1k000002.02.01.0
whitespace_text_1k000002200
todomvcTodoMVC workflows — add, complete, filter, edit, clear and destroy items, with native form/input events in the loop.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 8 iterations)
operationOctane (.tsrx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
add 1002.513171.12.21.82.3
toggle all on0.160.420.501.20.280.320.40
toggle all off0.160.420.500.880.280.280.38
complete 250.986.16.61.10.720.880.84
filter cycle0.741.21.30.980.980.961.3
edit 100.785.17.61.82.31.11.7
clear completed0.240.500.420.400.200.260.38
destroy 250.725.86.00.840.960.660.76
chat-streamChat UI workloads — token streaming, coarse updates, history append, conversation switches and text input.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 8 iterations)
operationOctane (.tsrx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
fine stream1.66.88.12.72.81.51.00
coarse stream0.421.32.50.700.840.660.60
append history1.25.4101.12.11.50.98
switch conversation2.63.23.34.56.04.04.4
type 160 chars1.14.33.30.500.840.940.56
js-framework-reorderThe keyed-reorder matrix — reverse, shuffle, rotations, prepends and displacements — stressing the keyed reconciler. Ripple’s prepend and insert-mid cells are omitted because their current identity gates fail; invalid timings are never charted.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 8 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
reverse1.00.971.92.01.0150.971.3
shuffle1.31.31.92.81.31.81.31.5
rotatef0.080.101.50.210.150.180.130.74
rotateb0.070.080.160.200.140.110.110.20
prepend1000.340.301.11.40.320.640.30
append1000.300.300.781.30.320.600.420.38
insertmid1000.340.300.921.40.360.740.34
removefirst0.020.040.140.200.070.110.060.03
removeevery100.120.160.260.300.170.180.160.20
displace30.060.100.151.30.140.110.130.21
displace40.070.100.151.30.160.120.120.21
displace50.070.100.161.30.160.120.110.20
displace60.070.090.161.30.150.120.120.22
displace80.080.110.171.30.160.120.110.22
dbmonThe DBMonster dashboard — high-frequency cell updates across a wall of database rows.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 30 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
mount3.74.07.08.6145.36.25.2
tick1.51.52.53.88.72.22.11.7
tick_partial0.460.521.42.51.30.680.650.54
remount4.24.57.89.8104.94.54.2
sort2.32.54.75.42.93.02.42.5
unmount1.71.92.82.42.91.81.81.9
effectful-listA 1,000-item list where every row runs effects and refs — the subsystems a plain row bench never touches.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 30 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
mount_1k8.38.710139.39.99.711
update_nodeps0.090.130.897.40.000.010.070.00
update_deps2.22.43.17.72.72.62.62.7
clear1.01.01.61.91.51.31.31.9
remount9.49.6121511111113
remove_100_scattered0.330.371.74.70.860.480.451.0
memo-wallMemo bail-out walls — parent re-renders against memoized subtrees, and context updates punching through them. React Compiler is shown separately from vanilla React; Solid, Svelte, Ripple and Vue Vapor have no parent re-render to absorb, so their near-zero wall ops are the fine-grained model’s honest number.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 20 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19React Compiler 1.0Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
mount131612121611121216
parent_rerender_equal_A0.000.100.150.000.210.000.010.070.00
parent_rerender_equal_B0.250.320.180.000.230.000.010.080.00
one_change_A0.000.100.170.160.220.020.050.100.02
one_change_B0.250.330.210.210.250.020.050.100.02
ctx_through_wall_A0.350.770.990.831.20.300.400.410.25
ctx_through_wall_B0.641.01.00.831.30.300.400.370.26
recursive-contextA deep recursive tree driven by context updates — mount, root and partial updates, unmount.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 20 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
mount4.27.05.24.64.5155.211
update_root0.541.20.651.20.540.540.550.34
update_partial0.050.110.090.070.040.090.020.04
partial_unmount0.040.040.090.050.040.090.040.01
partial_remount0.060.110.110.140.150.350.200.14
unmount0.522.10.750.990.480.790.370.66
signal-favoringDeep-tree state bumps at increasing depths — the workload shape signal frameworks are built around.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 20 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
mount1.41.92.81.51.81.71.91.8
bump_shallow0.000.020.050.050.000.000.000.00
bump_middle0.000.010.050.030.000.000.000.00
bump_deep0.000.000.050.010.000.000.000.00
bump_sweep0.030.080.400.230.010.020.010.01
bump_sweep_batched0.010.030.060.230.010.010.000.00
bump_sweep_reverse0.010.030.070.200.010.010.000.00
unmount0.160.150.150.150.110.150.140.11
portal-swarmMany portals mounting, opening, closing and re-rendering — dispatching through portal boundaries.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 20 iterations)
operationOctane (.tsrx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
mount_closed2.54.13.14.64.42.34.4
open_all1.31.43.41.22.83.12.1
rerender_open_A0.030.280.500.000.010.030
rerender_open_B0.260.300.490.000.010.030.00
rerender_open_B_stable0.230.170.250.000.010.030
open_close_cycle1.51.83.81.33.12.42.4
open_close_distinct1.82.13.71.33.12.62.4
dispatch_through_portal0.000.010.000.000.000.000.00
nodes_closed_main2622201420142614322826192618
elements_closed_main1411141114111411141114111411
text_closed_main603603603120312146081207
comments_closed_main6080006036000
nodes_open_main2822221422142614482826193818
comments_open_main60800014036000
nodes_open_body7025521752175617843162228021
elements_open_body3412341234123212341232123212
text_open_body1805180518052405361624104809
comments_open_body180800014036000
empty_text_open_body0006006056053004
whitespace_text_open_body2.02.02.02.012082.02.0
async-waterfallTen nested async levels with 16ms simulated latency — Octane’s compiled parallel-use path versus React and Preact nested-use waterfalls and signal-first models.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 10 iterations)
operationOctane (.tsrx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3
init19304175181918
update18177177181817
newsA news-site page: full SSR render and client hydration of the same app.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 20 iterations)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
SSR render0.060.050.080.070.040.020.020.02
hydrate1.51.72.51.81.81.51.11.7
streaming-ssrStreaming SSR shell and completion times for staggered Suspense and all-fast renders. Preact participates with its public stream renderer; Svelte 5 is omitted because its public server renderer is buffered.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 30 iterations)
operationOctane (.tsrx)React 19Preact 10Solid 2.0 betaRipple 0.3
staggered shell0.190.430.552.30.44
staggered complete5151525151
all-fast shell0.090.130.091.80.08
all-fast complete1.21.41.21.91.4
bundle-sizeProduction shipped JavaScript bytes with normalized minification — total gzip and app-code gzip across the rows, TodoMVC and chat fixtures.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (production build bytes)
operationOctane (.tsrx)Octane (.tsx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
rows total gzip18 kB33 kB61 kB10 kB14 kB18 kB13 kB
rows app gzip2 kB3 kB2 kB2 kB2 kB2 kB2 kB
Todo app gzip2 kB1 kB983 B1 kB1 kB2 kB1 kB
chat app gzip3 kB2 kB2 kB2 kB2 kB2 kB2 kB
ssr-throughputServer renders of the news page at 50 and 500 items — benchmark score ms per render.

geometric mean across all operations, × vs Octane (.tsrx) — lower is better

Data table (score ms, 10 iterations)
operationOctane (.tsrx)React 19Preact 10Solid 2.0 betaSvelte 5Ripple 0.3Vue Vapor 3.6 beta
news-500.030.100.090.060.040.030.04
news-5000.371.11.00.670.420.430.40

The authoring cliff

Octane against itself: what naively-authored code costs relative to the compiled fast path. The de-opt fixtures render the same apps through plain createElement — the shape every binding produces — so the cliff is a first-class, regression-guarded number.

js-framework — the authoring cliffThe same 1,000-row app authored four ways: tuned .tsrx, React-style naive .tsrx and .tsx, and plain-.ts createElement with no compiler involvement (the shape every binding produces).

geometric mean across all operations, × vs Tuned .tsrx — lower is better

Data table (score ms, 8 iterations)
operationTuned .tsrxNaive .tsrx (React-style)Naive .tsxPlain .ts createElement
run2.22.72.85.4
replace4.95.45.19.0
add1.82.32.37.7
update0.460.560.605.5
select0.120.120.180.14
swap0.540.840.687.8
remove0.280.360.464.0
runlots13161735
clear20192035
nodes_1k10074100741007410072
elements_1k8051805180518051
text_1k2021202120212021
comments_1k2.02.02.00
empty_text_1k0000
whitespace_text_1k0000
dbmon — de-opt pathThe exact dbmon workload in plain-.ts createElement (full descriptor reconciliation) against the compiled fixture.

geometric mean across all operations, × vs Compiled .tsrx — lower is better

Data table (score ms, 30 iterations)
operationCompiled .tsrxPlain .ts createElement
mount3.66.8
tick1.45.1
tick_partial0.464.0
remount4.17.1
sort2.26.8
unmount1.72.6
SSR scenariosOctane-only SSR shapes — suspense waterfalls by depth, a 32-wide fan-out, an escape-heavy page, and the de-opt page pair. Benchmark score ms per render.
Data table (score ms, 10 iterations)
operationOctane SSR
waterfall depth 10.04
waterfall depth 20.04
waterfall depth 40.06
depth 4 × 32 wide2.0
escape-heavy page3.3
de-opt page (fast)0.48
de-opt page (de-opted)1.3