ReactOct 17, 2026 · 7 min read

tanstack router vs react router, my two cents

Every React app I have ever shipped used React Router. It was never a decision. It was just what you did, like npm install and a src folder and arguing about semicolons in code review.

Then TanStack Router started showing up everywhere I looked. I spent a weekend reading both sets of docs side by side, and here is the honest version, no fanboy stuff either way.

Where React Router stands now

React Router v7 landed in late 2024 and merged with Remix, so it is a different animal than the v6 most of us learned. Everything lives in one package now, just react-router, and there are three modes: declarative (the classic Routes and Route components), data (createBrowserRouter with loaders and actions), and framework (file-based routes with SSR, basically the old Remix life). It is the safe default. Ten years of Stack Overflow answers exist for every problem you will hit.

What TanStack Router is actually selling

Type safety, end to end. That is the whole pitch, and it is a good one. You define a route tree, and TypeScript knows your params and your search params everywhere. Navigate to a route with the wrong params and you get a red squiggle in your editor instead of a blank page at runtime. It is at version 1.170 as I write this, and it is very actively maintained.

The differences that actually matter

  • Type-safe everything. TanStack infers params and search params straight from the route tree. React Router v7 added typegen, but it is a codegen step you have to remember to run.
  • Search params are first-class. TanStack has validateSearch, so you can validate query strings with zod and get typed search params out. React Router gives you useSearchParams, which is strings all the way down, and you parse them yourself. (I have written that parsing code more times than I want to admit.)
  • Data loading. Both do loaders. React Router v7 data mode is solid and familiar, and TanStack's loaders cover the same ground.
  • Code-based or file-based. TanStack does both, file-based through a Vite plugin. React Router v7 framework mode is file-based too. No clear winner here anymore.
  • Ecosystem. React Router wins by a mile. Newer does not mean worse, but it does mean fewer answered questions when you get stuck at 1am.

The code tells the story better than I can. Same route, both routers. First React Router v7:

react-router-example.tsxTypeScript
import { createBrowserRouter, useParams } from 'react-router'

const router = createBrowserRouter([
  { path: 'posts/:postId', element: <Post /> },
])

function Post() {
  const { postId } = useParams()
  // postId is string | undefined, your problem now
}

Now TanStack Router:

tanstack-router-example.tsxTypeScript
import { createRoute, createRootRoute } from '@tanstack/react-router'

const rootRoute = createRootRoute()

const postRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/posts/$postId',
  component: Post,
})

function Post() {
  const { postId } = postRoute.useParams()
  // postId is string. The compiler already checked it.
}

So which one

New TypeScript-heavy SPA and I want the compiler catching my routing mistakes: TanStack. A team that already knows React Router, or I need some obscure integration to already exist: React Router. The honest truth is the router is almost never the thing that makes or breaks an app. Pick the one your team will actually maintain, and move on to the real problems.

The best router is the one you stop thinking about.

So, what have I learnt?

That "default choice" and "best choice" are different things, and it is worth re-checking every couple of years. React Router earned its default status. TanStack Router earned a real look. I have not ripped out a working router for either of them, and neither should you.