Decision. For a client-rendered React 19 admin console where the URL carries filters, sorting and pagination, adopt TanStack Router ⭐ 15k — full type safety and schema-validated search params in pure SPA mode, no server required [landscape]. React Router ⭐ 56k (now v8) is the defensible default if you value the largest ecosystem over typed search state. Either way, keep data-fetching in a query library, skip the meta-framework, and don’t couple to route loaders — that combination keeps the router a thin, swappable dependency.
Five angles, one recurring fact underneath all of them: React Router’s strongest features live in framework mode — a server. Its typed path params, typed href, and loader/action data all fully materialise only when you run the full-stack framework [1][2]. Run React Router as a pure client SPA and you drop back to useLoaderData() as Post and untyped URLSearchParams [3]. TanStack Router’s typing is identical whether you SSR or not [4]. So for a deliberately client-rendered console the two routers are not evenly matched: React Router gives up its headline edge exactly where this app operates, and typed search-param state — filters, sort, pagination validated at the type boundary — is the one capability only TanStack provides natively [5].
That same “which mode?” fork settles the framework and data questions. RSC and meta-frameworks (Next.js App Router, React Router framework mode, TanStack Start) are optimisations for crawlers and first paint — an auth-gated internal console has neither, so a standalone router on Vite remains a first-class 2026 choice, not a legacy one [6][7]. And because there is no HTML stream in a CSR SPA, router loaders lose their reason to exist: a query library (RTK Query if you want OpenAPI codegen, else TanStack Query) should own fetching, caching and invalidation, with the router used at most to prime the cache [8][9].
The angles also reinforce each other on lock-in. Real lock-in comes from loaders/actions and file-route conventions [10] — the very coupling the data-loading angle already tells you to avoid. Follow that advice and either router stays cheap to leave (2–4 hours for a small SPA), and an existing React Router app can simply ride future.* flags forward via codemod [11].
Two costs remain genuinely open, both on the recommended pick. TanStack leans on “very advanced and complex types” with cryptic errors and a real learning curve [12]; and a May 2026 npm supply-chain compromise hit 42 @tanstack/* packages for ~20 minutes [13]. If the team isn’t TypeScript-first, React Router (data mode) is the lower-ceremony choice that trades typed search params for a gentler slope.