Four React routers, one fixture: a deliberately client-rendered React 19 admin console where the URL carries filters, sorting and pagination.
TanStack Router takes it on the URL-as-state axis — full type safety and schema-validated search params in pure SPA mode, no server required [2][1]. React Router is the safe runner-up: biggest ecosystem, least drama — but its type-safety edge lives in framework mode, a server, so a pure SPA gets less of it [8]. Wouter only for simple consoles; Next.js App Router is the wrong grain for a client-rendered SPA [7].
Cells are scored for a client-rendered React 19 admin SPA — not in the abstract. Next.js's 141k stars and server-first design are strengths in general; here, "server-first" is exactly what this deliberately client-only app doesn't want.
State-first routing (URL → state → data → UI). Purpose-built for client-heavy SPAs, dashboards and internal tools where the URL carries rich state, all validated at the type boundary.
UI-first routing (URL → component). The default React answer with the biggest ecosystem and least migration friction. Three additive modes — declarative, data, framework.
~2.2KB, hooks-based, mimics React Router's Route/Link/Switch with an optional top-level router. Excellent when routing should be near-invisible.
The "do you even need a standalone router" foil. It can be coerced into a static-export SPA with instant client transitions, but it is server-first by design and file-based only.