С любовью ко всем разработчикам на свете ❤️
Every number on this page comes from the open benchmark repo: github.com/1gr14/point0-benchmarks. The setup: the same app — a small blog plus a SaaS-style dashboard — built four times (Point0, Next.js, TanStack Start, React Router), each in its framework's native idiom, rendering the same content from the same deterministic in-memory store. A Playwright parity gate (22 assertions per app) must be green before any number counts; results are medians over repeated runs; raw per-run JSON is committed. This page is the short read — the repo README carries the full method and all tables.
Measured on an Apple M1 Pro: Point0 0.3.13, Next.js 16.3.2, TanStack Start
1.168.27, React Router 8.3.0, React 19.2.8 everywhere. Each framework runs on
its own supported runtime — Point0 on Bun 1.4.0, the others on Node 22.21.1 —
and every load number sits next to a bare Bun.serve / node:http floor, so
runtime and framework tax stay separable.
In the tables, every competitor cell carries a small delta vs Point0: green means that framework is better on the metric, red means worse. Point0's own cells stay bare.
| Point0 | Next.js | TanStack Start | React Router | |
|---|---|---|---|---|
| Runtime (as shipped) | Bun | Node | Node | Node |
| HMR, edit → DOM ↓ | 20 ms | 54 ms 2.7× | 175 ms 8.8× | 157 ms 7.9× |
| Dev start, warm ↓ | 972 ms | 1,924 ms +98% | 2,015 ms +107% | 1,263 ms +30% |
| Prod build, L (+500 pages) ↓ | 7.49 s | 10.87 s +45% | 18.20 s +143% | 4.47 s −40% |
| Editor re-check, L ↓ | 1.06 s | 0.82 s −23% | 1.07 s +1% | 0.96 s −9% |
| Cold type-check (CI), L · TS7 ↓ | 6.85 s | 0.23 s −97% | 0.58 s −92% | 1.12 s −84% |
| First-load JS, /post (gzip) ↓ | 150 kB | 136 kB −9% | 104 kB −31% | 103 kB −31% |
| Nav data payload, dashboard (gzip) ↓ | 470 B | 1,335 B +184% | 274 B −42% | 254 B −46% |
| Time-to-shell, /slow (streamed) ↓ | 7 ms | 10 ms +43% | 5 ms −29% | 5 ms −29% |
| SSR /post, req/s c64 ↑ * | 1,548 | 882 −43% | 3,284 +112% | 1,156 −25% |
| Prod cold start ↓ | 448 ms | 721 ms +61% | 100 ms −78% | 612 ms +37% |
| RSS idle ↓ | 348 MB | 363 MB +4% | 173 MB −50% | 251 MB −28% |
↓ lower is better · ↑ higher is better. * Point0's SSR row is its warmed
build (.onPrefetchPage, 0 re-renders) — the peer of the others' eager loaders;
the default lazy build does 1,200 req/s.
This is where Point0's advantage is concentrated, and it is the part of the table you touch most often.
Cold whole-project tsc and editor responsiveness are different metrics, and
conflating them is the usual mistake.
The cold check is Point0's clear cost. Inferring everything end-to-end with
zero annotations runs to 2.23M type instantiations at 500 pages — 6.85 s on
native TS7, 17.45 s on the JS tsc — against Next's 0.23 s and TanStack's 0.58
s. You pay that in CI, and it is a real bill.
The per-edit re-check — the lag you feel while typing — does not separate the
field. Point0 pages are isolated exports: there is no monolithic AppRouter
type to re-instantiate on each keystroke, and the generated route map is just
path strings.
| Per-edit re-check | Point0 | Next.js | TanStack Start | React Router |
|---|---|---|---|---|
| 4 pages | 0.94 s | 0.61 s −35% | 0.91 s −3% | 0.61 s −35% |
| 504 pages | 1.06 s | 0.82 s −23% | 1.07 s +1% | 0.96 s −9% |
All four stay flat from 4 pages to 504, and at any given size they sit within a third of a second of each other. Point0 sits at the slow end of that band — which is another way of saying this metric will not decide anything for you. The structural outlier is React Router's cold check: its typed routes grow combinatorially, from 10k instantiations at 4 pages to 4.35M at 504 — the largest count of the four — though native TS7 still clears it in 1.12 s.
After the first document, a Point0 navigation ships query data and never HTML. So do TanStack Start and React Router, and on the dashboard case — rich markup, tiny data, the shape of a real SaaS page — the three land close together: React Router 254 B, TanStack 274 B, Point0 470 B gzipped. At that scale the gaps between them do not matter. Next is the outlier at 1,335 B, because its RSC flight payload re-sends the rendered markup; the fair caveat is that Next prefetches every visible link, so those bytes move before the click rather than during it.
Felt latency does not differentiate either: a dashboard→dashboard click resolves in 30–33 ms on all four.
The other side of the ledger is first-load JS, and it is Point0's heaviest row: 150 kB gzipped against Next's 136 kB and TanStack's and React Router's ~103 kB. Point0 pays that once on the first load and collects on every click after.
Memory is a cost too, and it does not wash out. Against a bare Bun.serve +
renderToString floor of 118 MB, Point0 idles at 348 MB — about 230 MB of
framework tax — while TanStack sits ~38 MB above its Node floor. Point0 is the
second-heaviest of the four at idle.
Every framework here can stream a slow block into the same response after the
shell. On a page with one 1.5 s query, all four ship the shell in single-digit
milliseconds — Point0 in 7 ms via a .loading() fallback +
.query({ suspend: 'server' }), and the 5–10 ms spread across the four is noise
on a local server. The contrast row is Point0 with streaming off: the whole
document waits for the slow block and nothing appears until ~1,515 ms. That is
what streaming buys back, and Point0 makes it a per-query opt-in instead of an
architecture decision.
On raw SSR throughput with in-memory data, TanStack leads at 3,284 req/s — a real and large lead — followed by warmed Point0 at 1,548, default Point0 at 1,200, React Router at 1,156 and Next at 882.
Point0's default is a render-to-discover loop: it renders, sees which queries
the page needs, fetches them, re-renders — so you never declare a page's data
dependencies, which none of the other three offer. That convenience costs ~22%
(1,200 vs 1,548 req/s); one opt-in hook
(.onPrefetchPage(() => q.fetchQuery(...))) removes it.
Point0's SSR document carries data twice — markup plus the dehydrated React Query cache that makes every piece of data a live, cacheable query on the client. On a text-heavy post that is 6.5 kB raw vs TanStack's 3.8 kB, and gzip closes most of the gap: 2.19 kB vs 1.68 kB. Next's document is the largest of the four (8.9 kB raw, 2.44 kB gzipped), since RSC inlines its flight payload in a less compressible format.
Prod cold start is 448 ms — behind TanStack's 100 ms, ahead of React Router's 612 ms and Next's 721 ms. Part of that is deliberate: Point0 imports the whole app at boot, so a broken page fails the process at deploy time, not on a user's first request.
The SSR numbers above measure frameworks in a vacuum — the loader is trivial, so framework CPU is the whole latency. Add one realistic DB query and the differences stop existing:
| DB delay | Point0 | Next.js | TanStack Start | React Router |
|---|---|---|---|---|
| 0 ms | 0.90 ms | 2.00 ms | 0.39 ms | 1.23 ms |
| 5 ms | 8.22 ms | 8.26 ms | 8.19 ms | 8.70 ms |
| 20 ms | 25.14 ms | 25.82 ms | 25.16 ms | 26.01 ms |
At 5 ms the four land within half a millisecond of each other; at 20 ms, within a millisecond. Those are noise, not rankings — no delta you could act on. Any app that touches a database lives in the second regime, so the raw-SSR ordering describes frameworks in a vacuum and stops describing your app the moment a real query enters the loop. That is the reasoning behind where Point0 spends its budget: HMR, dev start and navigation payloads are costs a faster database cannot refund.
git clone https://github.com/1gr14/point0-benchmarks
cd point0-benchmarks
bun run setup # installs all four apps + Playwright
bun run parity # the gate — 22/22 must pass per app
bun run bench:all
bun run render # regenerates the README from results/Numbers are machine-dependent (except type instantiations and byte sizes, which are deterministic); the repo's manifest records the exact machine and versions behind every published table. If you find a setup that treats any framework unfairly — open an issue.