tanstack-start-architecture

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TanStack Start Architecture Enforcement

TanStack Start架构规范校验

Overview

概述

Enforces hypercore TanStack Start architecture rules with 100% compliance. Validates project structure, then applies strict layer/route/hook/convention rules to every code change.
This skill is RIGID. Follow exactly. No exceptions.
REQUIRED: When working on TanStack Start projects, ALWAYS use this skill together with
/oh-my-claudecode:ralph
to guarantee 100% architecture compliance. Ralph's persistence loop ensures every rule is verified and no violation slips through.
100%合规地强制执行核心TanStack Start架构规则,先校验项目结构,再对每一次代码变更应用严格的分层/路由/hook/约定规则。
本规范极其严格,必须完全遵守,无任何例外。
要求: 开发TanStack Start项目时,必须始终结合
/oh-my-claudecode:ralph
使用本规范,以确保100%符合架构要求。Ralph的持久化循环会校验所有规则,杜绝任何违规情况漏过。

Step 1: Project Validation

步骤1:项目校验

Before any work, confirm TanStack Start project:
bash
undefined
开展任何工作前,先确认是TanStack Start项目:
bash
undefined

Check for TanStack Start indicators (ANY of these)

检查TanStack Start标识(满足任意一项即可)

ls app.config.ts 2>/dev/null # TanStack Start config grep -r "@tanstack/react-start" package.json 2>/dev/null grep -r "@tanstack/react-router" package.json 2>/dev/null ls src/routes/__root.tsx 2>/dev/null

If NONE found: **STOP. This skill does not apply.** Inform user.

If found: proceed with architecture enforcement.
ls app.config.ts 2>/dev/null # TanStack Start配置文件 grep -r "@tanstack/react-start" package.json 2>/dev/null grep -r "@tanstack/react-router" package.json 2>/dev/null ls src/routes/__root.tsx 2>/dev/null

如果未找到任何标识:**停止操作,本规范不适用于当前项目,请告知用户。**

如果找到标识:继续执行架构校验流程。

Step 2: Read Architecture Rules

步骤2:阅读架构规则

Load the detailed rules reference:
REQUIRED: Read
architecture-rules.md
in this skill directory before writing any code.
For detailed patterns and examples, also read the relevant reference files:
  • rules/conventions.md
    - Code conventions (naming, TypeScript, imports, comments)
  • rules/routes.md
    - Route structure (folder rules, patterns, loaders)
  • rules/services.md
    - Server Functions (schemas, queries, mutations, middleware)
  • rules/hooks.md
    - Custom Hook patterns (separation rules, internal order)
加载详细的规则参考文档:
要求: 编写任何代码前,必须先阅读本技能目录下的
architecture-rules.md
文件。
如需了解详细模式和示例,还可阅读对应的参考文件:
  • rules/conventions.md
    - 代码约定(命名、TypeScript、导入、注释)
  • rules/routes.md
    - 路由结构(文件夹规则、模式、loaders)
  • rules/services.md
    - Server Functions(schema、查询、变更、中间件)
  • rules/hooks.md
    - 自定义Hook模式(分层规则、内部顺序)

Step 3: Pre-Change Validation Checklist

步骤3:变更前校验清单

Before writing ANY code, verify your planned change against these gates:
编写任何代码前,对照以下检查项确认你计划的变更符合要求:

Gate 1: Layer Violations

检查项1:分层违规

Routes -> Server Functions -> Features -> Database
CheckRule
Route accessing DB directly?BLOCKED. Must go through Server Functions -> Features
Route calling Prisma?BLOCKED. Use Server Functions
Server Function skipping Features?ALLOWED only for simple CRUD
Client calling Server Function directly?BLOCKED. Use TanStack Query (exception:
loader
/
beforeLoad
run server-side, can call directly)
Routes -> Server Functions -> Features -> Database
检查项规则
路由是否直接访问数据库?禁止,必须走Server Functions -> Features层
路由是否调用Prisma?禁止,请使用Server Functions
Server Function是否跳过Features层?仅简单CRUD场景允许
客户端是否直接调用Server Function?禁止,请使用TanStack Query(例外:
loader
/
beforeLoad
在服务端运行,可直接调用)

Gate 2: Route Structure

检查项2:路由结构

CheckRule
Flat file route? (
routes/users.tsx
)
BLOCKED. Use folder (
routes/users/index.tsx
)
Missing
-components/
folder?
BLOCKED. Every page needs it
Missing
-hooks/
folder?
BLOCKED. Every page needs it
Missing
-functions/
folder?
BLOCKED. Every page needs it
const Route
without
export
?
BLOCKED. Must be
export const Route
Logic in page component?BLOCKED. Extract to
-hooks/
Layout route missing
route.tsx
?
BLOCKED. Routes needing beforeLoad/loader must have
route.tsx
Route with search params but no
validateSearch
?
BLOCKED. Must use
zodValidator
with
validateSearch
Route without
pendingComponent
?
WARNING. Recommended for all routes with loaders
检查项规则
是否为扁平文件路由?(
routes/users.tsx
禁止,请使用文件夹结构(
routes/users/index.tsx
是否缺失
-components/
文件夹?
禁止,每个页面必须包含该文件夹
是否缺失
-hooks/
文件夹?
禁止,每个页面必须包含该文件夹
是否缺失
-functions/
文件夹?
禁止,每个页面必须包含该文件夹
const Route
是否没有
export
禁止,必须写为
export const Route
页面组件中是否包含业务逻辑?禁止,提取到
-hooks/
文件夹中
布局路由是否缺失
route.tsx
禁止,需要使用beforeLoad/loader的路由必须有
route.tsx
路由使用搜索参数但没有配置
validateSearch
禁止,必须结合
zodValidator
使用
validateSearch
路由没有配置
pendingComponent
警告,建议所有带loader的路由都配置该属性

Gate 3: Server Functions

检查项3:Server Functions

CheckRule
POST/PUT/PATCH without
inputValidator
?
BLOCKED
Auth-required without
middleware
?
BLOCKED
Using
.validator()
instead of
.inputValidator()
?
BLOCKED.
.validator()
does not exist
handler not last in chain?BLOCKED. handler must ALWAYS be last (middleware/inputValidator order is flexible)
Missing
zodValidator
adapter for search params?
BLOCKED. Use
zodValidator
from
@tanstack/zod-adapter
Direct server function call in component?BLOCKED. Use
useServerFn
hook from
@tanstack/react-start
functions/index.ts
barrel export?
BLOCKED. Tree shaking failure
检查项规则
POST/PUT/PATCH请求是否没有配置
inputValidator
禁止
需要鉴权的接口是否没有配置
middleware
禁止
是否使用
.validator()
而非
.inputValidator()
禁止,
.validator()
方法不存在
handler是否不在调用链末尾?禁止,handler必须始终放在最后(middleware/inputValidator的顺序可灵活调整)
搜索参数是否缺失
zodValidator
适配器?
禁止,请使用
@tanstack/zod-adapter
提供的
zodValidator
组件中是否直接调用Server Function?禁止,请使用
@tanstack/react-start
提供的
useServerFn
hook
是否存在
functions/index.ts
桶导出?
禁止,会导致tree shaking失效

Gate 4: Hooks

检查项4:Hooks

CheckRule
Hook inside page component?BLOCKED. Must be in
-hooks/
folder
Wrong hook order?BLOCKED. State -> Global -> Server Fns -> Query -> Handlers -> Memo -> Effect
Missing return type interface?BLOCKED
camelCase hook filename?BLOCKED. Use
use-kebab-case.ts
检查项规则
Hook是否写在页面组件内部?禁止,必须放在
-hooks/
文件夹中
Hook内部调用顺序是否错误?禁止,顺序必须为:State -> Global -> Server Fns -> Query -> Handlers -> Memo -> Effect
是否缺失返回类型定义?禁止
Hook文件名是否为驼峰命名?禁止,请使用
use-kebab-case.ts
格式

Gate 5: Conventions

检查项5:开发约定

CheckRule
camelCase filename?BLOCKED. Use kebab-case
function
keyword?
BLOCKED. Use const arrow function
any
type?
BLOCKED. Use
unknown
Missing explicit return type?BLOCKED
Wrong import order?BLOCKED. External -> @/ -> Relative -> Type
Missing Korean block comments?BLOCKED for code groups
Using
z.string().email()
pattern?
BLOCKED. Use Zod 4.x
z.email()
directly
检查项规则
文件名是否为驼峰命名?禁止,请使用短横线分隔命名
是否使用
function
关键字声明函数?
禁止,请使用const箭头函数
是否使用
any
类型?
禁止,请使用
unknown
是否缺失显式返回类型?禁止
导入顺序是否错误?禁止,顺序必须为:外部依赖 -> @/别名导入 -> 相对路径导入 -> 类型导入
是否缺失韩文块注释?代码组必须添加,禁止缺失
是否使用
z.string().email()
写法?
禁止,请直接使用Zod 4.x的
z.email()

Step 4: Implementation (with Ralph)

步骤4:落地实现(结合Ralph使用)

When used with ralph, every PRD story MUST include these acceptance criteria:
- [ ] Layer architecture respected (no layer skipping)
- [ ] Route uses folder structure with -components/, -hooks/, -functions/
- [ ] export const Route = createFileRoute(...) used
- [ ] Server Functions use correct chaining (handler always last, middleware/inputValidator flexible)
- [ ] Search params use zodValidator from @tanstack/zod-adapter
- [ ] Custom Hooks in -hooks/ with correct internal order
- [ ] All filenames kebab-case
- [ ] Korean block comments present
- [ ] const arrow functions with explicit return types
结合ralph使用时,每个PRD需求必须包含以下验收标准:
- [ ] 遵守分层架构要求(无跨层调用)
- [ ] 路由使用文件夹结构,包含`-components/`、`-hooks/`、`-functions/`
- [ ] 使用`export const Route = createFileRoute(...)`写法
- [ ] Server Functions使用正确的调用链(handler始终在末尾,middleware/inputValidator顺序灵活)
- [ ] 搜索参数使用`@tanstack/zod-adapter`提供的`zodValidator`
- [ ] 自定义Hook放在`-hooks/`文件夹中,内部调用顺序正确
- [ ] 所有文件名使用短横线分隔命名
- [ ] 存在韩文块注释
- [ ] 使用const箭头函数并声明显式返回类型

Step 5: Post-Change Verification

步骤5:变更后校验

After writing code, verify:
  1. Structure check:
    ls
    the route folder - confirm
    -components/
    ,
    -hooks/
    ,
    -functions/
    exist
  2. Export check: grep for
    export const Route
    in route files
  3. Layer check: no Prisma imports in route files
  4. Convention check: no camelCase filenames, no
    function
    keyword declarations
  5. Hook order check: read hook files, verify State -> Global -> Server Fns -> Query -> Handlers -> Memo -> Effect
编写完代码后,校验以下内容:
  1. 结构校验:执行
    ls
    查看路由文件夹,确认
    -components/
    -hooks/
    -functions/
    存在
  2. 导出校验:grep检查路由文件中是否包含
    export const Route
  3. 分层校验:路由文件中没有导入Prisma相关内容
  4. 约定校验:无驼峰命名的文件名,无
    function
    关键字声明的函数
  5. Hook顺序校验:查看Hook文件,确认顺序符合State -> Global -> Server Fns -> Query -> Handlers -> Memo -> Effect要求

Quick Reference: Folder Structure

快速参考:文件夹结构

src/
├── routes/                    # File-based routing
│   └── <page>/
│       ├── index.tsx          # Page (UI only)
│       ├── route.tsx          # Layout (beforeLoad, loader)
│       ├── -components/       # REQUIRED: page components
│       ├── -hooks/            # REQUIRED: page hooks (ALL logic here)
│       ├── -functions/        # REQUIRED: page server functions
│       └── -sections/         # Optional: 200+ line pages
├── features/<domain>/         # Internal domain (Prisma queries)
│   ├── schemas.ts
│   ├── queries.ts
│   └── mutations.ts
├── services/<provider>/       # External SDK wrappers
├── functions/                 # Global server functions (NO index.ts!)
│   └── middlewares/
├── database/                  # Prisma client singleton
├── stores/                    # Zustand stores
├── hooks/                     # Global hooks
├── components/                # Shared UI
│   ├── ui/                    # shadcn/ui
│   ├── layout/                # Header, Sidebar, Footer
│   └── shared/                # Common components
├── types/                     # Global types
├── env/                       # t3-env validation
├── config/                    # auth, query-client, sentry
└── lib/                       # Utilities
    ├── utils/
    ├── constants/
    └── validators/
src/
├── routes/                    # 基于文件的路由
│   └── <page>/
│       ├── index.tsx          # 页面(仅UI代码)
│       ├── route.tsx          # 布局(beforeLoad、loader逻辑)
│       ├── -components/       # 必填:页面专属组件
│       ├── -hooks/            # 必填:页面专属hooks(所有逻辑放在此处)
│       ├── -functions/        # 必填:页面专属server functions
│       └── -sections/         # 可选:代码超过200行的页面拆分模块
├── features/<domain>/         # 内部领域层(Prisma查询逻辑)
│   ├── schemas.ts
│   ├── queries.ts
│   └── mutations.ts
├── services/<provider>/       # 外部SDK封装层
├── functions/                 # 全局server functions(禁止添加index.ts!)
│   └── middlewares/
├── database/                  # Prisma client单例
├── stores/                    # Zustand stores
├── hooks/                     # 全局hooks
├── components/                # 共享UI组件
│   ├── ui/                    # shadcn/ui组件
│   ├── layout/                # 头部、侧边栏、底部组件
│   └── shared/                # 通用组件
├── types/                     # 全局类型定义
├── env/                       # t3-env校验
├── config/                    # auth、query-client、sentry配置
└── lib/                       # 工具函数
    ├── utils/
    ├── constants/
    └── validators/

Common Mistakes

常见错误

MistakeFix
routes/users.tsx
routes/users/index.tsx
const Route = createFileRoute(...)
export const Route = createFileRoute(...)
.validator(schema)
.inputValidator(schema)
Logic in page componentExtract to
-hooks/use-*.ts
lib/db
or
lib/store
folders
Use
database/
and
stores/
functions/index.ts
barrel
Import directly from individual files
Hook with mixed orderFollow: State -> Global -> Server Fns -> Query -> Handlers -> Memo -> Effect
getUserById.ts
filename
get-user-by-id.ts
function doThing() {}
const doThing = (): ReturnType => {}
Direct Zod schema in
validateSearch
Use
zodValidator(schema)
from
@tanstack/zod-adapter
Server function call without
useServerFn
Use
useServerFn(serverFn)
in components
createMiddleware()
without options
Use
createMiddleware({ type: 'function' })
Missing
pendingComponent
on route
Add
pendingComponent
for loading state
错误写法修复方案
routes/users.tsx
routes/users/index.tsx
const Route = createFileRoute(...)
export const Route = createFileRoute(...)
.validator(schema)
.inputValidator(schema)
页面组件中包含业务逻辑提取到
-hooks/use-*.ts
文件中
lib/db
lib/store
文件夹
使用
database/
stores/
文件夹
functions/index.ts
桶导出
直接从单个文件导入
Hook内部调用顺序混乱遵循:State -> Global -> Server Fns -> Query -> Handlers -> Memo -> Effect
getUserById.ts
文件名
get-user-by-id.ts
function doThing() {}
const doThing = (): ReturnType => {}
validateSearch
中直接写Zod schema
使用
@tanstack/zod-adapter
提供的
zodValidator(schema)
不通过
useServerFn
调用Server Function
组件中使用
useServerFn(serverFn)
createMiddleware()
没有传参数
使用
createMiddleware({ type: 'function' })
路由缺失
pendingComponent
添加
pendingComponent
作为加载状态

Red Flags - STOP and Fix

危险信号 - 立即停止并修复

  • Route file importing from
    @/database/prisma
    directly
  • Missing
    export
    on
    const Route
  • Page component with
    useState
    ,
    useQuery
    etc. inline (not in hook)
  • Server function using
    .validator()
    instead of
    .inputValidator()
  • any
    type anywhere
  • camelCase filenames
  • /api
    route handlers (use Server Functions)
  • Missing
    -hooks/
    folder in any route
  • Route using search params without
    validateSearch
  • Component calling server function directly (not through
    useServerFn
    )
  • createMiddleware()
    without
    { type: 'function' }
    option
  • 路由文件直接从
    @/database/prisma
    导入
  • const Route
    缺少
    export
    关键字
  • 页面组件内直接写
    useState
    useQuery
    等逻辑(未封装到hook中)
  • Server Function使用
    .validator()
    而非
    .inputValidator()
  • 任何位置使用
    any
    类型
  • 文件名使用驼峰命名
  • 存在
    /api
    路由处理器(请使用Server Functions)
  • 任意路由缺失
    -hooks/
    文件夹
  • 路由使用搜索参数但未配置
    validateSearch
  • 组件直接调用Server Function(未通过
    useServerFn
  • createMiddleware()
    未传
    { type: 'function' }
    参数