TanStack Router
一个面向 React 和 Solid 的客户端优先、服务端就绪、完全类型安全的全栈路由框架。
TanStack Router 是新一代类型安全路由框架,实现路由配置、导航、搜索参数的全链路类型推断,搜索参数作为一等公民状态内置 Schema 验证,支持文件路由和代码路由混合模式。
TanStack Router
一个面向 React 和 Solid 的客户端优先、服务端就绪、完全类型安全的全栈路由框架。
技术简介说明
TanStack Router 是由 TanStack 团队(创始人 Tanner Linsley,TanStack Query 作者)于 2023 年创建的新一代路由解决方案,定位为 React 和 Solid 生态中的类型安全路由框架。它从零开始设计,以 TypeScript 类型推断为核心,实现了路由配置、导航、搜索参数、路径参数和路由上下文的全链路类型安全——开发者无需手动编写类型注解,编译器即可在构建阶段捕获路由相关错误。这与 React Router 等依赖运行时字符串匹配的成熟方案形成鲜明对比,后者在编译期无法完整保留类型信息。
TanStack Router 将搜索参数(Search Params)视为一等公民状态,而非简单的 URL 字符串拼接。它内置了 JSON 序列化/反序列化、Schema 验证(支持 Zod v4 直接传入、Valibot、ArkType 等)和类型推断,使得复杂 URL 状态管理变得安全且可控。同时,框架提供了受 TanStack Query 启发的轻量级内置缓存(SWR 策略)、Suspense 友好的数据加载、路由预取、自动代码分割和原生 Devtools 等能力。它不依赖 history 或 path-to-regexp 等传统库,而是自行实现了完整的路由匹配引擎。
2025 年,TanStack 基于 Router 推出了 TanStack Start 全栈框架,支持 SSR、流式渲染、Server Functions、API Routes 等,直接对标 Next.js 和 React Router v7 的框架模式。截至 2026 年 7 月,TanStack Router 已拥有超过 14,800 GitHub Stars,npm 累计下载量突破 2.6 亿次,周下载量超过 2,100 万次(较 2025 年初的 ~300 万增长超过 7 倍),是 React 路由领域增长最快、最具创新力的竞争者。
基本信息
- 官网:https://tanstack.com/router/latest
- GitHub:https://github.com/TanStack/router
- License:MIT
- 最新版本(2026-07-01):
@tanstack/react-router:v1.170.17(稳定版)@tanstack/vue-router:v1.170.16(实验性)@tanstack/solid-router:v1.170.17(稳定版)@tanstack/solid-router:v2.0.0-beta.23(预发布版)@tanstack/router-core:v1.171.14@tanstack/router-plugin:v1.168.19@tanstack/react-start:v1.168.27@tanstack/router-devtools:v1.167.0
- 主要维护者/公司:Tanner Linsley 及 TanStack 核心团队(社区贡献者 100+)
- GitHub Stars:14,800+
- npm 周下载量:~2,150 万(2026-07)
- npm 总下载量:~2.616 亿
- 代码语言:TypeScript 98.3%
- 总发布次数:2,400+
- 支持框架:React(稳定)、Solid(稳定/v2 beta)、Vue(实验性)
快速上手
安装
使用文件路由(推荐)
# pnpm(推荐包管理器)
pnpm add @tanstack/react-router @tanstack/router-plugin
# npm
npm install @tanstack/react-router @tanstack/router-plugin
# yarn
yarn add @tanstack/react-router @tanstack/router-plugin还需要安装对应构建工具的插件:
# Vite 项目
pnpm add -D @tanstack/router-vite-plugin
# TanStack Start 项目(全栈)
pnpm create @tanstack/start@latest my-app
# Rsbuild 项目
pnpm add -D @tanstack/router-rsbuild-plugin
# Webpack 项目
pnpm add -D @tanstack/router-webpack-plugin
# ESBuild 项目
pnpm add -D @tanstack/router-esbuild-plugin使用代码路由(手动配置)
pnpm add @tanstack/react-router安装开发工具(推荐)
pnpm add @tanstack/router-devtools基础配置
Vite + 文件路由
// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { TanStackRouterVite } from '@tanstack/router-vite-plugin'
export default defineConfig({
plugins: [
react(),
TanStackRouterVite({
routesDirectory: './src/routes',
generatedRouteTree: './src/routeTree.gen.ts',
autoCodeSplitting: true,
}),
],
})TanStack Start 全栈项目
# 使用脚手架创建
pnpm create @tanstack/start@latest my-app
cd my-app
pnpm install
pnpm dev最小示例
代码路由模式
// src/main.tsx
import {
createRouter,
createRootRoute,
createRoute,
RouterProvider,
Outlet,
Link,
} from '@tanstack/react-router'
import ReactDOM from 'react-dom/client'
// 根路由
const rootRoute = createRootRoute({
component: () => (
<div>
<nav>
<Link to="/">首页</Link> | <Link to="/about">关于</Link>
</nav>
<hr />
<Outlet />
</div>
),
})
// 首页路由
const indexRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/',
component: () => <h1>首页</h1>,
})
// 关于页路由
const aboutRoute = createRoute({
getParentRoute: () => rootRoute,
path: '/about',
component: () => <h1>关于</h1>,
})
// 创建路由树
const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])
// 创建路由器实例
const router = createRouter({ routeTree })
// 类型注册(全局类型安全的关键步骤!)
declare module '@tanstack/react-router' {
interface Register {
router: typeof router
}
}
// 渲染
const rootElement = document.getElementById('root')!
ReactDOM.createRoot(rootElement).render(
<RouterProvider router={router} />
)文件路由模式(推荐)
// src/routes/__root.tsx
import { Outlet, Link, createRootRoute } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
export const Route = createRootRoute({
component: () => (
<>
<nav>
<Link to="/">首页</Link> | <Link to="/about">关于</Link>
</nav>
<hr />
<Outlet />
<TanStackRouterDevtools />
</>
),
})
// src/routes/index.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/')({
component: Index,
})
function Index() {
return <h1>首页</h1>
}
// src/routes/about.tsx
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute('/about')({
component: About,
})
function About() {
return <h1>关于</h1>
}文件路由模式下,routeTree.gen.ts 由插件自动生成,无需手动维护路由树。
核心概念与架构
1. 全链路类型安全
TanStack Router 的核心设计哲学是无损类型推断(Lossless Type Inference)。通过在路由定义中使用大量泛型参数,框架在整个 API 表面实现了类型自动传播:
- 路由定义 → 路径参数自动推断(如
/posts/$postId→{ postId: string }) - 搜索参数 →
validateSearch定义的 Schema 自动推断类型 - 导航 →
<Link>和navigate()的目标路径、参数、搜索参数均受类型约束 - 路由上下文 → 父路由定义的上下文自动传递给子路由
// 路径参数自动推断
const Route = createFileRoute('/posts/$postId')({
component: PostPage,
})
function PostPage() {
const { postId } = Route.useParams()
// postId 的类型为 string,而非 string | undefined
// 编译器在构建阶段即可捕获无效的路径参数
}2. 搜索参数作为一等状态
搜索参数不是简单的 URL 字符串,而是结构化的、经过验证的、类型安全的状态:
- 自动将 JSON 结构序列化为 URL 查询字符串
- 内置 Schema 验证(Zod v4 可直接传入、Valibot、ArkType)
- 参数通过路由树向下传递,子路由可以访问父路由的搜索参数
- 搜索参数中间件支持批量保留/剥离
import { z } from 'zod'
import { createFileRoute } from '@tanstack/react-router'
// Zod v4 直接传入 Schema,无需 adapter
const searchSchema = z.object({
page: z.number().int().nonnegative().catch(1),
filter: z.string().catch(''),
sort: z.enum(['asc', 'desc']).catch('asc'),
})
export const Route = createFileRoute('/products')({
validateSearch: searchSchema,
component: ProductsPage,
})
function ProductsPage() {
const { page, filter, sort } = Route.useSearch()
// page: number, filter: string, sort: 'asc' | 'desc'
// 全部类型安全,包含默认值
}3. 路由上下文(Route Context)
路由上下文是 TanStack Router 的分层依赖注入系统,支持同步和异步定义,非常适合管理认证、主题和全局工具函数:
// 根路由定义上下文类型契约
const rootRoute = createRootRouteWithContext<{
auth: AuthState
theme: Theme
}>()({
component: RootLayout,
beforeLoad: async () => {
const auth = await getAuthState()
return { auth, theme: getTheme() }
},
})
// 子路由自动继承上下文,类型安全
const dashboardRoute = createFileRoute('/dashboard')({
beforeLoad: ({ context }) => {
// context.auth 和 context.theme 类型安全
if (!context.auth.isLoggedIn) {
throw redirect({ to: '/login' })
}
},
component: DashboardPage,
})4. 数据加载与缓存
TanStack Router 提供内置的轻量级缓存(灵感来自 TanStack Query,但 API 更精简):
export const Route = createFileRoute('/posts')({
// 路由级数据加载
loader: async () => {
const posts = await fetchPosts()
return { posts }
},
// loader 依赖推导——搜索参数变化时自动重新加载
loaderDeps: ({ search }) => ({ page: search.page }),
// 内置 SWR 缓存策略
staleTime: 5 * 60 * 1000, // 5 分钟内数据视为新鲜
gcTime: 30 * 60 * 1000, // 30 分钟后缓存回收
// UI 状态管理
pendingComponent: () => <Spinner />,
errorComponent: ({ error }) => <ErrorBoundary error={error} />,
component: PostsPage,
})5. 文件路由 + 代码路由混合
TanStack Router 独创性地支持文件路由和代码路由在同一项目中并存,开发者可以根据不同模块的需求灵活选择。文件路由由插件自动生成路由树,代码路由手动组装,两者共享同一套类型系统。
6. 架构总览
┌─────────────────────────────────────────────────┐
│ TanStack Router │
├─────────────────────────────────────────────────┤
│ @tanstack/router-core (框架无关核心) │
│ ├── 路由定义 & 类型推断引擎 │
│ ├── 搜索参数序列化/反序列化 │
│ ├── 路径参数解析与匹配引擎 │
│ ├── 内置缓存(SWR) │
│ └── 导航 & 路由排序匹配 │
├─────────────────────────────────────────────────┤
│ @tanstack/react-router (React 适配层) │
│ ├── RouterProvider / Link / Outlet │
│ ├── useSearch / useParams / useNavigate │
│ └── Suspense / Error Boundary 集成 │
├─────────────────────────────────────────────────┤
│ @tanstack/router-plugin (构建工具插件) │
│ ├── 文件路由生成器 (routeTree.gen.ts) │
│ ├── 虚拟路由文件支持 │
│ └── 类型声明自动生成 │
├─────────────────────────────────────────────────┤
│ @tanstack/react-start (全栈框架) │
│ ├── SSR / Streaming │
│ ├── Server Functions (支持任意 HTTP 方法) │
│ ├── API Routes │
│ └── 中间件系统 │
└─────────────────────────────────────────────────┘
核心特性
-
全链路类型安全:路由路径、路径参数、搜索参数、导航目标、路由上下文全部自动推断,编译器在构建阶段即可捕获路由错误,无需手动编写类型注解。
-
搜索参数一等公民:搜索参数自动 JSON 序列化/反序列化,支持 Zod v4/Valibot/ArkType Schema 验证,参数在路由树中级联传递,支持中间件批量操作(
retainSearchParams/stripSearchParams)。 -
文件路由 + 代码路由混合:支持类 Next.js 的文件约定路由(自动生成路由树),同时保留完整的代码路由能力,两者可在同一项目中混合使用。
-
内置 SWR 缓存与数据加载:路由 loader 自带轻量级缓存(灵感来自 TanStack Query),支持
staleTime/gcTime配置、pendingComponent/errorComponentUI 状态管理,无需额外集成 React Query(当然也可以配合使用)。 -
自动预加载与代码分割:鼠标悬停
<Link>时自动预加载目标路由数据和代码;文件路由自动按路由边界进行代码分割(autoCodeSplitting)。 -
原生 Devtools:内置
@tanstack/router-devtools,可在浏览器中实时查看路由树、搜索参数、路由上下文、缓存状态和导航历史,与统一的 TanStack Devtools 面板集成。 -
SSR / Streaming 支持:通过 TanStack Start 框架提供完整的服务器端渲染和流式渲染能力,支持 Server Functions、API Routes 和中间件,可部署到 Vercel、Cloudflare Workers 等多种目标。
-
路由上下文分层注入:支持在根路由或任意路径上通过
createRootRouteWithContext同步/异步注入上下文,自动向子路由传递,实现类型安全的依赖注入。 -
导航拦截与生命周期:支持
beforeLoad、onEnter、onLeave、onTransition生命周期钩子,实现导航拦截、重定向、乐观更新和数据预取。 -
多框架支持:核心层(
@tanstack/router-core)框架无关,已适配 React(稳定)、Solid(稳定,已有 v2 beta)和 Vue(实验性)。
生态图
核心生态
TanStack 生态
├── TanStack Router ──────── 路由核心(本文主题)
│ ├── @tanstack/router-core ──── 框架无关核心
│ ├── @tanstack/react-router ─── React 适配
│ ├── @tanstack/solid-router ─── Solid 适配
│ ├── @tanstack/vue-router ───── Vue 适配(实验性)
│ ├── @tanstack/router-plugin ── 构建工具插件
│ ├── @tanstack/router-devtools ─ 开发者工具
│ └── @tanstack/router-generator ─ 路由树生成器
│
├── TanStack Start ──────── 全栈框架(基于 Router)
│ ├── @tanstack/react-start ──── React 全栈
│ └── @tanstack/solid-start ──── Solid 全栈
│
├── TanStack Query ──────── 服务端状态管理(独立,可配合使用)
├── TanStack Table ──────── 表格逻辑层(独立)
├── TanStack Form ───────── 表单管理(独立)
└── TanStack DB ─────────── 本地数据库(新兴)
关键依赖
| 依赖 | 用途 |
|---|---|
| Vite | 默认构建工具(TanStack Start 基于 Vite + Vinxi) |
| TypeScript ≥ 5.1 | 类型安全的基础(必须) |
| React ≥ 18 | 核心框架依赖 |
| Zod / Valibot / ArkType | 搜索参数 Schema 验证(可选,Zod v4 无需 adapter) |
| Vinxi | TanStack Start 的服务端框架 |
相关插件与扩展
- @tanstack/router-vite-plugin:Vite 文件路由插件
- @tanstack/router-webpack-plugin:Webpack 文件路由插件
- @tanstack/router-rsbuild-plugin:Rsbuild 文件路由插件
- @tanstack/router-esbuild-plugin:ESBuild 文件路由插件
- @tanstack/router-devtools:路由调试工具
- @tanstack/router-zod-adapter:Zod v3 搜索参数适配器(Zod v4 不再需要)
社区生态
- TanStack Devtools:统一开发者工具面板,支持路由调试、缓存检查、导航历史追踪
- 迁移工具:官方提供 React Router v7 → TanStack Router 迁移指南
- Smithery Skills:社区提供的 Claude Code AI 迁移技能包
- Headless CMS 集成:Cosmic 等提供 TanStack Router 集成模板
- 社区适配器:各种部署平台和框架集成
适用场景
1. TypeScript 优先的中大型应用
当项目以 TypeScript 编写且路由逻辑复杂时,TanStack Router 的类型安全能显著减少运行时错误。编译器在构建阶段即可捕获路径拼写错误、参数类型不匹配和无效导航目标,对于需要严格类型约束的团队尤其有价值。
2. 复杂 URL 状态管理
对于依赖 URL 搜索参数驱动页面状态的页面(如电商筛选、数据表格分页排序、搜索引擎),TanStack Router 的 Schema 验证和 JSON 搜索参数是理想选择,避免了手动解析 URL 的繁琐和错误。
3. 需要路由级数据加载的应用
TanStack Router 的路由 loader 与内置缓存配合,可以在路由级别管理数据获取,结合 pendingComponent 和 errorComponent 实现优雅的加载和错误状态处理。
4. 多路由层级的认证与权限控制
路由上下文的分层注入机制使得在路由级别实现认证检查、权限守卫和主题切换变得自然,beforeLoad 钩子支持异步逻辑和重定向。
5. 需要 SSR 但不想绑定 Next.js 的项目
TanStack Start 提供了不依赖 Next.js 的全栈方案,支持 Cloudflare Workers、Vercel 等多种部署目标,适合希望保持技术栈灵活性和轻量运行时的团队。
6. 需要精确导航体验的应用
悬停预加载、路由预取、自动代码分割和滚动恢复等特性,使得 TanStack Router 在追求极致用户体验和高性能的应用中表现出色。
7. 从 React Router 迁移的团队
官方提供了完整的迁移指南,对于已使用 React Router 但希望获得更强类型安全的项目,迁移路径清晰,两者在数据加载和路由定义方面概念相似。
开发与工程化
开发流程
# 1. 创建项目(推荐 TanStack Start 脚手架)
pnpm create @tanstack/start@latest my-app
# 或使用 Vite 模板
npx create-tsrouter-app@latest my-app --template vite
# 2. 启动开发服务器
cd my-app
pnpm dev
# 3. 添加新路由
# 文件路由模式下,只需在 src/routes/ 下创建文件即可
# 例如:src/routes/posts.$postId.tsx → /posts/:postId
# 路由树自动生成器会实时更新 routeTree.gen.ts
# 4. 类型检查
pnpm typecheck
# 5. 构建
pnpm build文件路由目录结构
src/
├── routes/
│ ├── __root.tsx # 根布局(必须)
│ ├── index.tsx # / 首页
│ ├── about.tsx # /about
│ ├── posts/
│ │ ├── index.tsx # /posts 列表
│ │ └── $postId.tsx # /posts/:postId 详情
│ ├── _auth/ # 无路径布局路由(共享布局)
│ │ ├── login.tsx # /login
│ │ └── register.tsx # /register
│ ├── _dashboard/
│ │ ├── index.tsx # /dashboard
│ │ └── settings.tsx # /dashboard/settings
│ └── $.tsx # 404 通配符路由
├── routeTree.gen.ts # 自动生成,不要手动编辑
└── main.tsx
路由命名约定
| 文件名 | 路由路径 | 说明 |
|---|---|---|
index.tsx | / | 索引路由 |
about.tsx | /about | 静态路由 |
$postId.tsx | /:postId | 动态参数路由 |
posts.$postId.tsx | /posts/:postId | 嵌套动态路由 |
_layout.tsx | (无 URL 段) | 布局路由(路径无关) |
_.tsx | 父路径的索引 | 路径索引路由 |
$.tsx | /* | 通配符/404 路由 |
构建部署
# 生产构建
pnpm build
# 预览构建产物
pnpm preview
# 部署到 Vercel
npx vercel
# 部署到 Cloudflare
npx wrangler deploy
# Docker 部署
# 使用 Node.js 服务器运行构建产物CI/CD 集成
# GitHub Actions 示例
name: CI
on: [push, pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'
- run: pnpm install
- run: pnpm typecheck # 类型检查(验证路由类型安全)
- run: pnpm build # 构建(验证路由树生成)
- run: pnpm test # 运行测试类型安全性能优化
TanStack Router 的类型推断在大型项目中可能影响 TypeScript 编译速度,以下是官方推荐的优化策略:
// 1. 限制 loader 返回类型的影响范围
// 如果 loader 数据仅用于缓存而非渲染,用 async 包装避免重类型推断
loader: async (): Promise<void> => {
await prefetchData() // 只缓存,不返回数据给组件
}
// 2. 使用 from/to 限制搜索参数推断范围
// 避免让 TypeScript 评估所有路由的搜索参数并集
<Link from="/posts" to="/posts/$postId" params={{ postId: '1' }}>
// 3. 大型路由树使用对象而非元组传递子路由
// 加速 TypeScript 类型检查
rootRoute.addChildren({ indexRoute, aboutRoute }) // ✅ 对象形式
// 而非 rootRoute.addChildren([indexRoute, aboutRoute]) // 元组形式
// 4. 使用 as const satisfies 缩小 prop 类型
const options = { /* ... */ } as const satisfies RouteOptions测试
import { render, screen } from '@testing-library/react'
import { createRouter, createMemoryHistory, RouterProvider } from '@tanstack/react-router'
import { Route } from './routes/__root'
test('渲染首页路由', () => {
const router = createRouter({
routeTree: Route,
history: createMemoryHistory({ initialEntries: ['/'] }),
})
render(<RouterProvider router={router} />)
expect(screen.getByText('首页')).toBeInTheDocument()
})性能与安全
性能特点
- 零运行时类型开销:类型安全完全在编译期实现,不影响运行时性能
- 自动代码分割:文件路由模式下,每个路由自动独立打包,支持按需加载
- 悬停预加载:用户悬停
<Link>时自动预加载目标路由的代码和数据 - 内置 SWR 缓存:路由 loader 数据自带缓存,减少重复请求
- 路由预取:通过
router.preloadRoute()或preloadIntent属性主动预取路由 - 并行数据加载:多个路由的 loader 并行执行,避免串行等待
- 零拷贝帧载荷提取:
start-client-core在 2026 年的版本中优化了帧载荷提取性能(#7662) - 路由排序匹配:基于路由优先级(ranked routes)的智能匹配,避免不必要的路由遍历
安全注意事项
- 搜索参数验证:所有来自 URL 的搜索参数通过
validateSearchSchema 验证,防止非法输入 - XSS 防护:React 默认转义渲染内容,但需确保 loader 返回的数据不包含未经验证的外部输入
- 路由鉴权:在
beforeLoad中统一处理权限验证和重定向 - CSRF:表单提交需要自行实现 CSRF 保护(TanStack Router 不内置此功能)
⚠️ 2026 年 5 月供应链攻击事件
重要安全事件:2026 年 5 月 11 日,TanStack 的 42 个 @tanstack/* npm 包遭到协调供应链攻击(被称为 "Mini Shai-Hulud"),共发布 84 个恶意版本。攻击者通过混淆代码在安装阶段窃取云凭据、VCS 凭据和注册表令牌,并在 Linux 和 macOS 上建立持久化后台服务。恶意载荷还包含威胁性逻辑——如果受害者撤销被盗令牌,将触发数据擦除。
影响:该事件主要影响在攻击窗口期安装了受影响版本的开发者。
应对措施:
- 确保安装的是官方最新版本(攻击版本已被 npm 撤回)
- 检查项目的
pnpm-lock.yaml/package-lock.json中的@tanstack/*包版本 - 使用
pnpm audit或npm audit检查依赖安全 - 启用 npm 2FA 和 provenance 验证
- 参考 GitHub 安全公告 GHSA-g7cv-rxg3-hmpx
已知性能瓶颈
- 大型路由树编译:数百个路由的项目中,TypeScript 类型推断可能显著增加编译时间(通过上述优化策略缓解)
- 路由树生成:
routeTree.gen.ts的生成在文件数量极多时可能变慢,建议合理组织路由目录 - IDE 性能:超大路由树可能影响 TypeScript 语言服务的响应速度
- 运行时路由匹配:路由匹配本身性能优异,瓶颈通常在 loader 数据获取而非匹配算法
技术对比
TanStack Router vs React Router v7
| 特性 | TanStack Router v1 | React Router v7 |
|---|---|---|
| 类型安全 | ✅ 全链路自动推断 | 🟡 仅框架模式部分支持 |
| 搜索参数验证 | ✅ Schema 验证 + JSON 序列化 | 🛐 无内置支持,需手动解析 |
| 搜索参数类型推断 | ✅ 自动推断 | 🔶 需自定义代码 |
| 搜索参数中间件 | ✅ 保留/剥离/自定义 | 🛐 无 |
| 导航类型安全 | ✅ 完整(路径 + 参数 + 搜索) | 🟡 部分支持 |
| 数据加载 | ✅ 内置 SWR 缓存 | ✅ Loader 函数 |
| 文件路由 | ✅ 原生支持 | ✅ 框架模式支持 |
| 代码路由 | ✅ 完整支持 | ✅ 库模式支持 |
| 文件 + 代码混合 | ✅ 支持 | 🛐 不支持 |
| 路由预取 | ✅ 悬停预加载 | ✅ prefetch |
| Devtools | ✅ 原生内置 | 🟠 社区插件 |
| SSR / Streaming | ✅ 通过 TanStack Start | ✅ 框架模式支持 |
| Server Functions | ✅ 支持任意 HTTP 方法 | ✅ 支持 |
| 运行时路由操作 | 🛐 不支持(静态路由树) | ✅ "Fog of War" 动态路由 |
| Form API | 🔶 需配合外部库 | ✅ 原生 <Form> 组件 |
| 多框架支持 | ✅ React / Solid / Vue | 🛐 仅 React |
| 成熟度 | 🟡 v1 稳定,快速增长 | ✅ 历史悠久,生态庞大 |
| 包体积 | ~30KB gzipped | ~45KB gzipped |
| npm 周下载量 | ~2,150 万 | ~6,000 万+ |
| GitHub Stars | 14,800+ | 55,000+ |
TanStack Router vs Next.js(App Router)
| 特性 | TanStack Router + Start | Next.js App Router |
|---|---|---|
| 类型安全 | ✅ 全链路 | 🟡 部分 |
| 框架独立性 | ✅ 不绑定特定平台 | 🔶 强绑定 Next.js 生态 |
| 部署灵活性 | ✅ Vercel / CF / 自建 | 🟡 最佳体验限 Vercel |
| 搜索参数管理 | ✅ Schema 验证 | 🔶 手动处理 |
| 学习曲线 | 🟡 需学习新概念 | 🟡 需理解 RSC 模型 |
| 生态丰富度 | 🟡 快速增长 | ✅ 极其丰富 |
| 运行时开销 | ✅ 轻量 | 🟡 较重的运行时 |
| 社区规模 | 🟡 增长中 | ✅ 极大 |
最佳实践
生产环境建议
1. 始终使用 validateSearch 验证搜索参数
// ✅ 推荐:使用 Zod Schema 验证
import { z } from 'zod'
export const Route = createFileRoute('/search')({
validateSearch: z.object({
q: z.string().min(1).catch(''),
page: z.number().int().nonnegative().catch(1),
sort: z.enum(['relevance', 'date', 'price']).catch('relevance'),
}),
})
// ❌ 避免:手动解析 URL 搜索参数
const params = new URLSearchParams(location.search)
const page = parseInt(params.get('page') || '1') // 不类型安全2. 使用 .catch() 而非 .default() 处理无效参数
// ✅ 推荐:.catch() 在验证失败时优雅降级
z.object({
page: z.number().catch(1), // 无效值时默认为 1,不抛错
})
// ❌ 避免:.default() 可能导致意外行为
z.object({
page: z.number().default(1), // 仅在值缺失时生效,无效值仍抛错
})3. 使用 from 属性限制类型推断范围
// ✅ 推荐:明确指定来源路由
<Link from="/posts" search={(prev) => ({ ...prev, page: 2 })}>
下一页
</Link>
// ❌ 避免:不指定 from 导致推断所有路由的搜索参数并集
<Link search={(prev) => ({ ...prev, page: 2 })}>
下一页
</Link>4. 合理使用路由上下文进行认证
// ✅ 推荐:在 beforeLoad 中处理认证
const protectedRoute = createFileRoute('/dashboard')({
beforeLoad: async ({ context }) => {
if (!context.auth.isAuthenticated) {
throw redirect({ to: '/login', search: { redirect: location.href } })
}
},
})
// ✅ 推荐:使用 createRootRouteWithContext 建立类型契约
const rootRoute = createRootRouteWithContext<{
auth: AuthService
api: ApiClient
}>()({
component: RootLayout,
beforeLoad: () => ({
auth: createAuthService(),
api: createApiClient(),
}),
})5. 大型项目的路由组织
src/routes/
├── __root.tsx # 根布局
├── index.tsx # 首页
├── _layout/ # 共享布局(不产生路径)
│ ├── dashboard.tsx
│ └── settings.tsx
├── (auth)/ # 路由分组(不产生路径前缀)
│ ├── login.tsx
│ └── register.tsx
└── api/ # API 路由(TanStack Start)
└── users.ts
6. 搜索参数驱动的列表页
export const Route = createFileRoute('/posts')({
validateSearch: z.object({
page: z.number().catch(1),
pageSize: z.number().catch(20),
sort: z.enum(['asc', 'desc']).catch('desc'),
query: z.string().catch(''),
}),
loaderDeps: ({ search }) => search,
loader: async ({ deps: { page, pageSize, sort, query } }) => {
return fetchPosts({ page, pageSize, sort, query })
},
})常见陷阱
- 忘记注册 Router 类型:必须在模块声明中注册 Router 实例,否则全局 hooks(
useNavigate、useParams等)无法获得类型推断 routeTree.gen.ts被手动修改:此文件由插件自动生成,手动修改会在下次生成时被覆盖- 搜索参数类型丢失:在文件路由中,子路由必须使用正确的文件命名(如
posts.$postId.tsx)或getParentRoute来继承父路由的搜索参数类型 - 大型 Schema 导致编译缓慢:过于复杂的
validateSearchSchema 可能拖慢 TypeScript 编译,建议合理拆分或使用from/to限制推断范围 - 不要在 loader 中执行副作用:loader 应专注于数据获取,不应修改全局状态或产生副作用
- 忽略
from属性:不指定from会导致 TypeScript 推断所有路由的搜索参数并集,影响编译速度和类型精度
技术局限与边界
已知限制
-
静态路由树:TanStack Router 的路由树在构建时确定,不支持运行时动态添加/移除路由(React Router 的 "Fog of War" 特性)。对于需要运行时动态路由的场景(如插件系统),灵活性不如 React Router。
-
TypeScript 编译开销:类型安全的代价是 TypeScript 编译时间增加。在拥有数百个路由的大型项目中,可能需要采用优化策略(
from/to限定、对象形式addChildren、loader 返回类型限制)来缓解。 -
框架绑定:虽然核心是框架无关的,但成熟度最高的适配是 React,Solid 已有 v2 beta,Vue 仍为实验性。如果目标框架不在支持列表中,则无法使用。
-
生态成熟度:相比 React Router 十余年的积累,TanStack Router 的第三方集成、教程、社区解答相对较少。遇到问题时可能需要直接查阅源码或 GitHub Issues。
-
Server Components 支持:React Server Components 支持目前仍处于实验阶段,两个主流框架(包括 React Router)均未完全落地。
-
版本迭代频繁:截至 2026-07 已有 2,400+ releases,升级时需关注 CHANGELOG 中的 Breaking Changes。
不适用场景
- 非 TypeScript 项目:TanStack Router 的核心价值依赖 TypeScript 类型推断,纯 JavaScript 项目中优势大幅降低
- 极简单的路由需求:1-2 个页面的简单应用无需引入 TanStack Router 的复杂性
- 需要运行时动态路由的插件系统:静态路由树设计不适合需要运行时注册路由的场景
- React Native 应用:专注于 Web 路由,不适用于移动端原生导航(React Navigation 更合适)
- 团队不熟悉 TypeScript:类型系统较为复杂,新手需要时间适应
迁移注意事项
- 从 React Router 迁移:官方提供了迁移指南,主要差异在于路由定义方式、数据加载 API 和搜索参数处理。建议渐进式迁移,先在非核心模块试用。
- 从 React Router v7 框架模式迁移:两者在文件路由和数据加载方面概念相似,迁移成本相对较低。
- 从 Next.js 迁移:需要重新组织路由结构和数据获取方式,工作量较大。
学习资源
官方文档
- TanStack Router 官方文档 — 最权威的学习入口
- 快速开始 — 从零搭建项目
- 搜索参数验证指南 — Schema 验证详解(Zod/Valibot/ArkType)
- 类型安全指南 — 类型推断原理和最佳实践
- 搜索参数设置 — 搜索参数入门
- React Router 迁移指南 — 从 React Router 迁移
- 官方对比文档 — 与 React Router 的详细功能对比
- TanStack Start 文档 — 全栈框架文档
- Search Params Are State — 官方博文,阐述搜索参数即状态的设计理念
教程与课程
- The Only TanStack Router Crash Course You Need (2026) — 2026 年最新完整教程
- TanStack Start Full Course 2026 — 全栈框架完整课程
- Complete Intro to React v9 — TanStack Router — Brian Holt 的 React 课程中的 Router 章节
- TanStack Router: Query Parameters & Validation — 搜索参数验证专题视频
- Modern, Scalable Applications with TanStack Router — Telerik 实战教程(2025-08)
- Build Type-Safe React Apps with File-Based Routing — 文件路由完整教程
深度文章
- TanStack Router vs React Router v7 — 架构和特性全面对比(2026-01)
- Beyond Next.js: TanStack Start — 全栈框架的未来展望
- TanStack Router Type-Safe Routing 2026 — 2026 年类型安全路由实践
- TanStack Router vs React Router — Better Stack 对比指南(2026-01)
社区资源
- TanStack Discord — 官方 Discord 社区,活跃的技术交流频道
- GitHub Discussions — 功能讨论、问题解答和方案分享
- GitHub Issues — Bug 报告和特性请求
- r/reactjs — Reddit React 社区,TanStack Router 话题活跃
- devtools.fm Episode 52: Tanner Linsley — 创始人访谈,分享 Router 设计理念和 TypeScript 优先的未来
- Semgrep 供应链攻击分析 — 2026 年安全事件详细分析
2026 年现状
最新版本与发布节奏
截至 2026 年 7 月:
- @tanstack/react-router:v1.170.17(稳定版,2026-07-01 发布)
- @tanstack/solid-router:v2.0.0-beta.23(2.0 预发布,2026-07-03)
- 总发布次数:2,400+(迭代极其频繁)
- 发布节奏:几乎每天都有修复或改进发布
社区活跃度
- GitHub Stars:14,800+
- npm 周下载量:从 2025 年初的 ~300 万增长到 2026 年的 ~2,150 万,增长超过 7 倍
- 贡献者:100+ 活跃贡献者
- Open Issues:~320(维护积极)
- Open PRs:~312
发展趋势
-
TanStack Start 成为全栈竞争者:2025 年底 v1 稳定后,TanStack Start 正在成为 Next.js 的可行替代方案,特别是在追求部署灵活性和轻量运行时的场景中。支持 Cloudflare Workers、Vercel 等多种部署目标。
-
Solid 支持进入 v2:Solid 适配即将发布 2.0 稳定版,框架支持进一步成熟。
-
Vue 实验性支持:
@tanstack/vue-router已发布 v1.170.16,正在逐步完善。 -
性能持续优化:2026 年的版本持续引入性能优化,如零拷贝帧载荷提取(#7662)、CI 工作流 OOM 修复、URL 不安全字符编码保留(#7695)等。
-
安全意识提升:经历 2026 年 5 月供应链攻击后,社区对依赖安全性的关注度显著提高,TanStack 团队也在加强安全实践。
未来路线图
- React Server Components:目前实验性支持,预计随 React 生态成熟逐步完善
- 路由并行加载(Parallel Routes):目前两个主流框架(包括 React Router)均未官方支持,是社区呼声较高的特性
- Devtools 扩展:Rsbuild 等新构建工具的 Devtools 插件开发中
- TanStack DB 集成:本地数据库能力与路由数据加载的深度整合
- 路由树编译性能优化:持续优化大型项目的 TypeScript 编译速度
总结:TanStack Router 是 2025–2026 年 React 路由领域最重要的创新力量。它通过全链路类型安全、搜索参数一等公民和内置数据管理,重新定义了 React 应用的路由开发体验。如果你的项目以 TypeScript 为主且路由逻辑复杂(尤其是搜索参数驱动的状态管理),TanStack Router 是 2026 年最值得认真评估的路由方案。对于需要全栈能力的场景,搭配 TanStack Start 可以构建不依赖 Next.js 的灵活全栈应用。