tanstack-router
TanStack Router is a type-safe, data-driven routing library for React, Solid, and Vue applications. It provides end-to-end TypeScript safety for routes, parameters, search params, and data loading, wi
TanStack Router
TanStack Router is a type-safe, data-driven routing library for React, Solid, and Vue applications. It provides end-to-end TypeScript safety for routes, parameters, search params, and data loading, with built-in caching, prefetching, and invalidation support. The router supports both file-based routing (recommended) and code-based routing, making it easy to organize your routes while maintaining full type safety across the entire application.
Quick References
| File | Purpose |
|---|---|
packages/react-router/src/index.tsx | Main React router package entry point |
packages/solid-router/src/index.tsx | SolidJS router entry point |
packages/vue-router/src/index.tsx | Vue router entry point |
packages/router-core/src/index.ts | Core framework-agnostic routing logic |
README.md | Project overview and documentation links |
Packages
| Package | npm name | Description |
|---|---|---|
packages/react-router | @tanstack/react-router | React routing with hooks and components |
packages/solid-router | @tanstack/solid-router | SolidJS routing with primitives |
packages/vue-router | @tanstack/vue-router | Vue routing with composables |
packages/react-start | @tanstack/react-start | Full-stack framework built on React Router |
packages/router-core | @tanstack/router-core | Core logic for all router packages |
packages/router-vite-plugin | @tanstack/router-vite-plugin | Vite plugin for file-based routing |
packages/zod-adapter | @tanstack/zod-adapter | Zod validator for search params |
packages/valibot-adapter | @tanstack/valibot-adapter | Valibot validator for search params |
packages/arktype-adapter | @tanstack/arktype-adapter | ArkType validator for search params |
packages/react-router-devtools | @tanstack/react-router-devtools | React Router devtools panel |
packages/solid-router-devtools | @tanstack/solid-router-devtools | Solid Router devtools panel |
packages/vue-router-devtools | @tanstack/vue-router-devtools | Vue Router devtools panel |
When to Use
- Building a React, Solid, or Vue application that needs a type-safe routing solution
- Implementing data loading and caching with automatic TypeScript inference
- Creating complex navigation patterns with nested layouts and pathless routes
- Building applications that require URL state management with validation
- Developing full-stack applications with server rendering and streaming (with TanStack Start)
- Working with dynamic routes, search parameters, and complex routing logic
Installation
# For React
npm install @tanstack/react-router
# For Solid
npm install @tanstack/solid-router
# For Vue
npm install @tanstack/vue-router
# For search params validation (recommended)
npm install @tanstack/zod-adapter zod
# For Vite file-based routing plugin
npm install -D @tanstack/router-vite-plugin
# For devtools (optional)
npm install -D @tanstack/react-router-devtools
Best Practices
-
Always use schema validation for search parameters - Use Zod, Valibot, or ArkType adapters to ensure type-safe, validated search parameters with fallback values for graceful error handling
-
Register your router for full type safety - Always add the
declare moduleaugmentation after creating your router to enable TypeScript inference across your entire application -
Prefer file-based routing - File-based routing is the recommended approach as it provides better organization, automatic code-splitting, and enhanced type safety through route generation
-
Use loaders for data fetching - Route loaders provide a consistent way to fetch data before rendering, with caching, invalidation, and TypeScript inference built-in
-
Implement proper error boundaries - Use
errorComponentandnotFoundComponentto handle errors and missing routes gracefully
Common Patterns
Code-based routing setup:
import { createRootRoute, createRoute, createRouter, RouterProvider } from '@tanstack/react-router'
const rootRoute = createRootRoute({
component: RootComponent,
})
const postsRoute = createRoute({
getParentRoute: () => rootRoute,
path: 'posts',
loader: () => fetchPosts(),
})
const postRoute = createRoute({
getParentRoute: () => postsRoute,
path: '$postId',
loader: ({ params }) => fetchPost(params.postId),
component: PostComponent,
})
const routeTree = rootRoute.addChildren([
postsRoute.addChildren([postRoute]),
])
const router = createRouter({
routeTree,
defaultPreload: 'intent',
defaultStaleTime: 5000,
scrollRestoration: true,
})
// Register for type safety
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
File-based routing with Vite plugin:
// vite.config.js
import { defineConfig } from 'vite'
import { tanstackRouter } from '@tanstack/router-plugin/vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [
tanstackRouter({
target: 'react',
autoCodeSplitting: true,
}),
react(),
],
})
File-based route definition:
// routes/__root.tsx
import { createRootRoute, Link, Outlet } from '@tanstack/react-router'
export const Route = createRootRoute({
component: () => (
<div>
<nav>
<Link to="/">Home</Link>
<Link to="/posts">Posts</Link>
</nav>
<Outlet />
</div>
),
})
// routes/posts.$postId.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/posts/$postId')({
loader: async ({ params: { postId } }) => fetchPost(postId),
component: PostComponent,
})
function PostComponent() {
const post = Route.useLoaderData()
return <div>{post.title}</div>
}
Search params with Zod validation:
import { createFileRoute } from '@tanstack/react-router'
import { zodValidator, fallback } from '@tanstack/zod-adapter'
import { z } from 'zod'
const searchSchema = z.object({
page: fallback(z.number(), 1).default(1),
category: fallback(z.string(), 'all').default('all'),
})
export const Route = createFileRoute('/products')({
validateSearch: zodValidator(searchSchema),
component: ProductsPage,
})
function ProductsPage() {
const { page, category } = Route.useSearch()
return <div>Page {page}, Category: {category}</div>
}
Navigation with parameters:
import { useNavigate } from '@tanstack/react-router'
function MyComponent() {
const navigate = useNavigate()
const goToPost = (postId: string) => {
navigate({ to: '/posts/$postId', params: { postId } })
}
return <button onClick={() => goToPost('123')}>View Post</button>
}
API Quick Reference
Router Setup
| Export | Type | Description |
|---|---|---|
createRootRoute | Function | Creates the root/parent route for all other routes |
createRootRouteWithContext | Function | Creates root route with shared context (e.g., QueryClient) |
createRoute | Function | Creates a route for code-based routing |
createFileRoute | Function | Creates a route for file-based routing |
createRouter | Function | Creates the router instance with route tree and options |
RouterProvider | Component | Provides router context to your React application |
Components
| Export | Type | Description |
|---|---|---|
Link | Component | Navigation |