tanstack-start by tanstack-skills/tanstack-skills
npx skills add https://github.com/tanstack-skills/tanstack-skills --skill tanstack-startTanStack Start 是一个基于 TanStack Router 构建的全栈 React 框架,由 Vite 和 Nitro(通过 Vinxi)驱动。它提供服务器端渲染、流式传输、服务器函数(RPC)、中间件、API 路由,并可通过 Nitro 预设部署到任何平台。
包: @tanstack/react-start 路由插件: @tanstack/router-plugin 构建工具: Vinxi (Vite + Nitro) 状态: RC(候选发布版) RSC 支持: React 服务器组件支持正在积极开发中,将作为非破坏性的 v1.x 版本新增功能发布。
npx @tanstack/cli create my-app
# 或手动安装:
npm install @tanstack/react-start @tanstack/react-router react react-dom
npm install -D @tanstack/router-plugin typescript vite vite-tsconfig-paths
my-app/
app/
routes/
__root.tsx # 根布局
index.tsx # / 路由
posts.$postId.tsx # /posts/:postId
api/
users.ts # /api/users API 路由
client.tsx # 客户端入口
router.tsx # 路由器创建
ssr.tsx # SSR 入口
routeTree.gen.ts # 自动生成的路由树
app.config.ts # TanStack Start 配置
tsconfig.json
package.json
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
app.config.ts)import { defineConfig } from '@tanstack/react-start/config'
import viteTsConfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
vite: {
plugins: [
viteTsConfigPaths({ projects: ['./tsconfig.json'] }),
],
},
server: {
preset: 'node-server', // 'vercel' | 'netlify' | 'cloudflare-pages' | 等
},
tsr: {
appDirectory: './app',
routesDirectory: './app/routes',
generatedRouteTree: './app/routeTree.gen.ts',
},
})
createServerFn)服务器函数提供客户端和服务器之间类型安全的 RPC 调用。
import { createServerFn } from '@tanstack/react-start'
// GET(数据获取,可缓存)
const getUsers = createServerFn()
.handler(async () => {
const users = await db.query.users.findMany()
return users
})
// POST(变更、副作用)
const createUser = createServerFn({ method: 'POST' })
.validator((data: { name: string; email: string }) => data)
.handler(async ({ data }) => {
const user = await db.insert(users).values(data).returning()
return user
})
import { z } from 'zod'
const updateUser = createServerFn({ method: 'POST' })
.validator(
z.object({
id: z.string(),
name: z.string().min(1),
email: z.string().email(),
})
)
.handler(async ({ data }) => {
// data 是完全类型化的:{ id: string; name: string; email: string }
return await db.update(users).set(data).where(eq(users.id, data.id))
})
import { createMiddleware } from '@tanstack/react-start'
const loggingMiddleware = createMiddleware().handler(async ({ next }) => {
console.log('请求开始')
const result = await next()
console.log('请求完成')
return result
})
const authMiddleware = createMiddleware().handler(async ({ next }) => {
const request = getWebRequest()
const session = await getSession(request)
if (!session?.user) {
throw redirect({ to: '/login' })
}
// 将类型化的上下文传递给处理器
return next({ context: { user: session.user } })
})
const adminMiddleware = createMiddleware()
.middleware([authMiddleware])
.handler(async ({ next, context }) => {
// context.user 来自 authMiddleware,已类型化
if (context.user.role !== 'admin') {
throw redirect({ to: '/unauthorized' })
}
return next({ context: { isAdmin: true } })
})
// 使用示例
const adminAction = createServerFn({ method: 'POST' })
.middleware([adminMiddleware])
.handler(async ({ context }) => {
// context: { user: User; isAdmin: boolean }
return { success: true }
})
// app/routes/api/users.ts
import { createAPIFileRoute } from '@tanstack/react-start/api'
export const APIRoute = createAPIFileRoute('/api/users')({
GET: async ({ request }) => {
const users = await db.query.users.findMany()
return Response.json(users)
},
POST: async ({ request }) => {
const body = await request.json()
const user = await db.insert(users).values(body).returning()
return new Response(JSON.stringify(user), { status: 201 })
},
})
export const Route = createFileRoute('/dashboard')({
loader: async () => ({
criticalData: await fetchCriticalData(),
deferredData: defer(fetchSlowData()),
}),
component: Dashboard,
})
function Dashboard() {
const { criticalData, deferredData } = Route.useLoaderData()
return (
<div>
<CriticalSection data={criticalData} />
<Suspense fallback={<Loading />}>
<Await promise={deferredData}>
{(data) => <SlowSection data={data} />}
</Await>
</Suspense>
</div>
)
}
// app.config.ts
export default defineConfig({
server: {
preset: 'node-server', // 自托管 Node.js
// preset: 'vercel', // Vercel
// preset: 'netlify', // Netlify
// preset: 'cloudflare-pages', // Cloudflare Pages
// preset: 'aws-lambda', // AWS Lambda
// preset: 'deno-server', // Deno Deploy
// preset: 'bun', // Bun
},
})
createServerFn GET 进行数据获取(可缓存、可预加载)createServerFn POST 进行变更和副作用操作beforeLoad 进行路由级别的认证守卫defer() 处理非关键数据以改善 TTFB(首字节时间)defaultPreload: 'intent' 以实现即时导航await 会导致流式传输问题declare module '@tanstack/react-router' 会导致所有类型安全丢失每周安装量
213
代码仓库
GitHub 星标数
5
首次出现
2026年2月21日
安全审计
安装于
codex201
cursor200
opencode200
gemini-cli199
github-copilot198
kimi-cli198
TanStack Start is a full-stack React framework built on TanStack Router, powered by Vite and Nitro (via Vinxi). It provides server-side rendering, streaming, server functions (RPC), middleware, API routes, and deploys to any platform via Nitro presets.
Package: @tanstack/react-start Router Plugin: @tanstack/router-plugin Build Tool: Vinxi (Vite + Nitro) Status: RC (Release Candidate) RSC Support: React Server Components support is in active development and will land as a non-breaking v1.x addition
npx @tanstack/cli create my-app
# Or manually:
npm install @tanstack/react-start @tanstack/react-router react react-dom
npm install -D @tanstack/router-plugin typescript vite vite-tsconfig-paths
my-app/
app/
routes/
__root.tsx # Root layout
index.tsx # / route
posts.$postId.tsx # /posts/:postId
api/
users.ts # /api/users API route
client.tsx # Client entry
router.tsx # Router creation
ssr.tsx # SSR entry
routeTree.gen.ts # Auto-generated route tree
app.config.ts # TanStack Start config
tsconfig.json
package.json
app.config.ts)import { defineConfig } from '@tanstack/react-start/config'
import viteTsConfigPaths from 'vite-tsconfig-paths'
export default defineConfig({
vite: {
plugins: [
viteTsConfigPaths({ projects: ['./tsconfig.json'] }),
],
},
server: {
preset: 'node-server', // 'vercel' | 'netlify' | 'cloudflare-pages' | etc.
},
tsr: {
appDirectory: './app',
routesDirectory: './app/routes',
generatedRouteTree: './app/routeTree.gen.ts',
},
})
createServerFn)Server functions provide type-safe RPC calls between client and server.
import { createServerFn } from '@tanstack/react-start'
// GET (data fetching, cacheable)
const getUsers = createServerFn()
.handler(async () => {
const users = await db.query.users.findMany()
return users
})
// POST (mutations, side effects)
const createUser = createServerFn({ method: 'POST' })
.validator((data: { name: string; email: string }) => data)
.handler(async ({ data }) => {
const user = await db.insert(users).values(data).returning()
return user
})
import { z } from 'zod'
const updateUser = createServerFn({ method: 'POST' })
.validator(
z.object({
id: z.string(),
name: z.string().min(1),
email: z.string().email(),
})
)
.handler(async ({ data }) => {
// data is fully typed: { id: string; name: string; email: string }
return await db.update(users).set(data).where(eq(users.id, data.id))
})
import { createMiddleware } from '@tanstack/react-start'
const loggingMiddleware = createMiddleware().handler(async ({ next }) => {
console.log('Request started')
const result = await next()
console.log('Request completed')
return result
})
const authMiddleware = createMiddleware().handler(async ({ next }) => {
const request = getWebRequest()
const session = await getSession(request)
if (!session?.user) {
throw redirect({ to: '/login' })
}
// Pass typed context to handler
return next({ context: { user: session.user } })
})
const adminMiddleware = createMiddleware()
.middleware([authMiddleware])
.handler(async ({ next, context }) => {
// context.user is typed from authMiddleware
if (context.user.role !== 'admin') {
throw redirect({ to: '/unauthorized' })
}
return next({ context: { isAdmin: true } })
})
// Usage
const adminAction = createServerFn({ method: 'POST' })
.middleware([adminMiddleware])
.handler(async ({ context }) => {
// context: { user: User; isAdmin: boolean }
return { success: true }
})
// app/routes/api/users.ts
import { createAPIFileRoute } from '@tanstack/react-start/api'
export const APIRoute = createAPIFileRoute('/api/users')({
GET: async ({ request }) => {
const users = await db.query.users.findMany()
return Response.json(users)
},
POST: async ({ request }) => {
const body = await request.json()
const user = await db.insert(users).values(body).returning()
return new Response(JSON.stringify(user), { status: 201 })
},
})
export const Route = createFileRoute('/dashboard')({
loader: async () => ({
criticalData: await fetchCriticalData(),
deferredData: defer(fetchSlowData()),
}),
component: Dashboard,
})
function Dashboard() {
const { criticalData, deferredData } = Route.useLoaderData()
return (
<div>
<CriticalSection data={criticalData} />
<Suspense fallback={<Loading />}>
<Await promise={deferredData}>
{(data) => <SlowSection data={data} />}
</Await>
</Suspense>
</div>
)
}
// app.config.ts
export default defineConfig({
server: {
preset: 'node-server', // Self-hosted Node.js
// preset: 'vercel', // Vercel
// preset: 'netlify', // Netlify
// preset: 'cloudflare-pages', // Cloudflare Pages
// preset: 'aws-lambda', // AWS Lambda
// preset: 'deno-server', // Deno Deploy
// preset: 'bun', // Bun
},
})
createServerFn GET for data fetching (cacheable, preloadable)createServerFn POST for mutations and side effectsbeforeLoad for route-level auth guardsdefer() for non-critical data to improve TTFBdefaultPreload: 'intent' on the router for instant navigationawait in loaders leads to streaming issuesdeclare module '@tanstack/react-router' loses all type safetyWeekly Installs
213
Repository
GitHub Stars
5
First Seen
Feb 21, 2026
Security Audits
Gen Agent Trust HubWarnSocketPassSnykPass
Installed on
codex201
cursor200
opencode200
gemini-cli199
github-copilot198
kimi-cli198
Flutter应用架构设计指南:分层结构、数据层实现与最佳实践
4,100 周安装
GrepAI trace callers:快速追踪函数调用者,代码重构与影响分析利器
348 周安装
Salesforce AI Agentforce 开发指南:Builder 智能体维护与元数据配置
370 周安装
GTM定位策略:如何通过词语选择与测试找到可防御的市场定位 | 产品营销指南
160 周安装
GrepAI Ollama 本地安装配置教程 - 私有化代码搜索嵌入模型设置指南
356 周安装
Strapi v5 专家:插件开发、自定义API与CMS架构最佳实践指南
363 周安装
Firebase应用托管基础教程:部署Next.js、Angular全栈Web应用
358 周安装