Performance (measured)

Real numbers, not a hunch — measured on this deployment. bext's interactivity floor (the JS a client pays to make an island interactive) is in the single-digit kilobytes, and zero before interaction in lazy mode.

Interactivity JS, compressed (gzip)

What a client downloads to make a counter interactive. The resume runtime (~3KB) is cached once across every island and page; each extra island adds only ~0.6KB — or nothing until interaction.

React + ReactDOM45 KB
SolidStart (solid-js)7 KB
bext — island + shared rt3.5 KB
bext — each extra island0
bext — lazy, before interaction0
Tip
This is the framework floor, not a site's total. A heavy site (including this demo template, with its syntax highlighting and embedded editors) ships its own chrome on top. The point isn't that every bext page is tiny — it's that the framework doesn't force a heavy baseline on you: the floor is ~13× lighter than React's ~45KB (and each extra island ~75×), and zero before interaction.

Head-to-head: the same app in five frameworks (measured)

We built the same app — a server-rendered 24-product grid + counter, theme toggle and search filter, all verified in a real browser — in all five frameworks, then forced each to render fresh on every request (no cache, no prerender; proven by a timestamp that changes on every request). Production builds and servers on activ-2; RPS/TTFB via oha -c 50.

FrameworkClient JS (gz)TTFBRPS (uncached)p99Build
bext (PRISM)5.6 KB6.0 ms4,74271 ms~4 KB*
Astro0.33 KB12.3 ms3,80720 ms432 KB
Remix101 KB12.2 ms1,01175 ms335 KB
Qwik35 KB42.6 ms93873 ms249 KB
Next.js145 KB21.1 ms575141 ms5.2 MB
Tip
Even uncached, bext renders fastest (Next's force-dynamic dropped it from 2,945 to 575 RPS — it had been serving prerendered static, not rendering). With its built-in ISR cache — one config line, not a CDN — the same route serves 282,776 RPS at 0.13 ms TTFB. The uncached 4,742 is bext's worst case, and it still wins. * bext has no heavyweight build: it compiles on demand.

Time to First Byte

Rust render + ISR cache. The full resumability page leaves in ~18ms (first-byte and total are the same over the local network), across three warm requests.

~18 ms

Methodology (reproducible)

reproduce.shShell
# interactivity floor — gzipped bytes a client actually pays
curl -s https://demo.bext.dev/islands/ResumableCounter.js | gzip -c | wc -c   # 589
curl -s https://demo.bext.dev/islands/__resume-runtime.js  | gzip -c | wc -c   # 2970 (cached once)

# TTFB (Rust + ISR cache) — three warm samples
for i in 1 2 3; do curl -s -o /dev/null \
  -w '%{time_starttransfer}s\n' https://demo.bext.dev/examples/resumability; done
#  → 0.018s  0.020s  0.019s

# full harness (TTFB + JS bytes + request count per page)
node harnesses/browser/bench.mjs