React Router Has a Type Safety Problem
React Router URLs are strings. Params are any. Links can point to routes that do not exist. You discover broken links in production.
TanStack Router: Fully Type-Safe
import { createFileRoute } from "@tanstack/react-router"
export const Route = createFileRoute("/users/$userId")({
loader: async ({ params }) => {
// params.userId is typed as string — not any
return fetchUser(params.userId)
},
component: UserPage
})
function UserPage() {
const { userId } = Route.useParams()
// TypeScript knows userId exists and is a string
const user = Route.useLoaderData()
// user is fully typed from the loader return
return <h1>{user.name}</h1>
}
Type-Safe Links
// This compiles
<Link to="/users/$userId" params={{ userId: "123" }} />
// This FAILS at compile time
<Link to="/users/$userId" params={{ id: "123" }} />
// Error: Object literal may only specify known properties
Broken links caught at compile time, not in production.
Search Params (Type-Safe!)
export const Route = createFileRoute("/search")({
validateSearch: z.object({
q: z.string().default(""),
page: z.number().default(1),
sort: z.enum(["date", "relevance"]).default("relevance")
})
})
// In components:
const { q, page, sort } = Route.useSearch()
// All typed. All validated. All with defaults.
TanStack Router vs React Router
| Feature | TanStack Router | React Router |
|---|---|---|
| Type safety | Full | Partial |
| Search params | Type-safe + validated | Strings |
| Code splitting | Automatic | Manual |
| Data loading | Built-in | Limited |
| File-based routing | Yes | No |
Build data-driven React apps. 88+ scrapers on Apify. Custom: spinov001@gmail.com
Top comments (0)