convex-tanstack

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Convex + TanStack Start

Convex + TanStack Start

Overview

概述

This skill provides guidance for building reactive, real-time full-stack applications using Convex (reactive backend-as-a-service) with TanStack Start (full-stack React meta-framework). The stack provides live-updating queries, type-safe end-to-end development, SSR support, and automatic cache invalidation.
本技能为使用Convex(响应式后端即服务)搭配TanStack Start(全栈React元框架)构建响应式、实时全栈应用提供指导。该技术栈支持实时更新查询、端到端类型安全开发、SSR支持以及自动缓存失效。

When to Use This Skill

何时使用本技能

  • Implementing Convex queries, mutations, or actions
  • Setting up or troubleshooting Better Auth authentication
  • Configuring TanStack Router routes and loaders
  • Writing schema definitions and indexes
  • Implementing data fetching patterns (useQuery, useSuspenseQuery)
  • Working with file storage, scheduling, or cron jobs
  • Building AI agents with @convex-dev/agent
  • Debugging SSR or hydration issues
  • 实现Convex查询、变更或操作
  • 搭建或排查Better Auth认证问题
  • 配置TanStack Router路由与加载器
  • 编写Schema定义与索引
  • 实现数据获取模式(useQuery、useSuspenseQuery)
  • 处理文件存储、任务调度或定时任务
  • 使用@convex-dev/agent构建AI Agent
  • 调试SSR或hydration问题

Quick Reference

快速参考

Essential Imports

必要导入

typescript
// Data fetching (always use cached version)
import { useQuery } from 'convex-helpers/react/cache'
import { useMutation, useAction } from 'convex/react'

// SSR with React Query
import { useSuspenseQuery } from '@tanstack/react-query'
import { convexQuery } from '@convex-dev/react-query'

// API and types
import { api } from '~/convex/_generated/api'
import type { Id, Doc } from '~/convex/_generated/dataModel'

// Backend functions
import { query, mutation, action } from "./_generated/server"
import { v } from "convex/values"
typescript
// 数据获取(请始终使用缓存版本)
import { useQuery } from 'convex-helpers/react/cache'
import { useMutation, useAction } from 'convex/react'

// 基于React Query的SSR
import { useSuspenseQuery } from '@tanstack/react-query'
import { convexQuery } from '@convex-dev/react-query'

// API与类型
import { api } from '~/convex/_generated/api'
import type { Id, Doc } from '~/convex/_generated/dataModel'

// 后端函数
import { query, mutation, action } from "./_generated/server"
import { v } from "convex/values"

The Skip Pattern

跳过模式

Never call hooks conditionally. Use
"skip"
instead:
typescript
const user = useQuery(api.users.get, userId ? { userId } : "skip")
const org = useQuery(api.orgs.get, user?.orgId ? { orgId: user.orgId } : "skip")
切勿条件式调用hooks,请使用"skip"替代:
typescript
const user = useQuery(api.users.get, userId ? { userId } : "skip")
const org = useQuery(api.orgs.get, user?.orgId ? { orgId: user.orgId } : "skip")

Three-State Query Handling

三状态查询处理

typescript
if (data === undefined) return <Skeleton />  // Loading
if (data === null) return <NotFound />       // Not found
return <Content data={data} />               // Success
typescript
if (data === undefined) return <Skeleton />  // 加载中
if (data === null) return <NotFound />       // 未找到
return <Content data={data} />               // 加载成功

Function Syntax (Always Include Returns Validator)

函数语法(请始终包含返回值验证器)

typescript
export const getUser = query({
  args: { userId: v.id("users") },
  returns: v.union(
    v.object({ _id: v.id("users"), name: v.string() }),
    v.null()
  ),
  handler: async (ctx, args) => {
    return await ctx.db.get(args.userId)
  },
})
typescript
export const getUser = query({
  args: { userId: v.id("users") },
  returns: v.union(
    v.object({ _id: v.id("users"), name: v.string() }),
    v.null()
  ),
  handler: async (ctx, args) => {
    return await ctx.db.get(args.userId)
  },
})

Index Best Practices

索引最佳实践

typescript
// Schema - name includes all fields
.index("by_organizationId_status", ["organizationId", "status"])

// Query - fields in same order as index
.withIndex("by_organizationId_status", (q) =>
  q.eq("organizationId", orgId).eq("status", "published")
)
typescript
// Schema - 名称需包含所有字段
.index("by_organizationId_status", ["organizationId", "status"])

// 查询 - 字段顺序需与索引一致
.withIndex("by_organizationId_status", (q) =>
  q.eq("organizationId", orgId).eq("status", "published")
)

Auth Check (Backend)

后端认证检查

typescript
import { authComponent } from "./auth"

const user = await authComponent.getAuthUser(ctx)
if (!user) throw new Error("Not authenticated")
typescript
import { authComponent } from "./auth"

const user = await authComponent.getAuthUser(ctx)
if (!user) throw new Error("未认证")

Core Principles

核心原则

  1. Use queries for reads - Queries are reactive, cacheable, and consistent
  2. Keep functions fast - Finish in < 100ms, work with < a few hundred records
  3. Prefer queries/mutations over actions - Actions are for external API calls only
  4. Always use indexes - Never do table scans with
    .filter()
  5. Minimize client state - Rely on Convex's real-time sync
  1. 使用查询进行读取操作 - 查询是响应式、可缓存且一致性的
  2. 保持函数快速 - 执行时间<100ms,处理记录数<几百条
  3. 优先使用查询/变更而非操作 - 操作仅用于外部API调用
  4. 始终使用索引 - 切勿使用
    .filter()
    进行全表扫描
  5. 最小化客户端状态 - 依赖Convex的实时同步

Common Anti-Patterns

常见反模式

WrongCorrect
import { useQuery } from 'convex/react'
import { useQuery } from 'convex-helpers/react/cache'
if (id) useQuery(...)
useQuery(..., id ? {...} : "skip")
.filter(x => x.field === val)
.withIndex("by_field", q => q.eq("field", val))
Action with
ctx.db
Use
ctx.runQuery/runMutation
`count
错误做法正确做法
import { useQuery } from 'convex/react'
import { useQuery } from 'convex-helpers/react/cache'
if (id) useQuery(...)
useQuery(..., id ? {...} : "skip")
.filter(x => x.field === val)
.withIndex("by_field", q => q.eq("field", val))
操作中使用
ctx.db
使用
ctx.runQuery/runMutation
`count

Reference Files

参考文件

Load the appropriate reference file based on the task:
FileUse When
references/01-setup.md
Project setup, config files, environment variables
references/02-router.md
Router setup, root route, file-based routing, layouts
references/03-auth.md
Better Auth setup, sign up/in/out, protected routes, SSR auth
references/04-data-fetching.md
useQuery, useSuspenseQuery, mutations, loaders, prefetching
references/05-backend.md
Schema, queries, mutations, actions, internal functions, HTTP endpoints
references/06-types.md
TypeScript patterns, validators, type mapping
references/07-storage.md
File upload, download, metadata, deletion
references/08-scheduling.md
scheduler.runAfter, cron jobs
references/09-agents.md
AI agents, tools, RAG setup
references/10-frontend.md
Component patterns, loading states, Tailwind/shadcn
references/11-permissions.md
Role hierarchy, feature access patterns
references/12-deployment.md
Dev commands, Convex CLI, Vercel deployment
references/13-quick-reference.md
Import cheatsheet, common patterns summary
根据任务加载对应的参考文件:
文件使用场景
references/01-setup.md
项目搭建、配置文件、环境变量
references/02-router.md
路由搭建、根路由、基于文件的路由、布局
references/03-auth.md
Better Auth搭建、注册/登录/登出、受保护路由、SSR认证
references/04-data-fetching.md
useQuery、useSuspenseQuery、变更、加载器、预获取
references/05-backend.md
Schema、查询、变更、操作、内部函数、HTTP端点
references/06-types.md
TypeScript模式、验证器、类型映射
references/07-storage.md
文件上传、下载、元数据、删除
references/08-scheduling.md
scheduler.runAfter、定时任务
references/09-agents.md
AI Agent、工具、RAG搭建
references/10-frontend.md
组件模式、加载状态、Tailwind/shadcn
references/11-permissions.md
角色层级、功能访问模式
references/12-deployment.md
开发命令、Convex CLI、Vercel部署
references/13-quick-reference.md
导入速查表、常见模式汇总

When to Load References

何时加载参考文件

  • Starting a new project: Load
    01-setup.md
  • Adding authentication: Load
    03-auth.md
  • Writing backend functions: Load
    05-backend.md
  • Implementing data fetching: Load
    04-data-fetching.md
  • Building UI components: Load
    10-frontend.md
  • Need quick syntax: Load
    13-quick-reference.md
  • 启动新项目:加载
    01-setup.md
  • 添加认证功能:加载
    03-auth.md
  • 编写后端函数:加载
    05-backend.md
  • 实现数据获取:加载
    04-data-fetching.md
  • 构建UI组件:加载
    10-frontend.md
  • 需要快速语法参考:加载
    13-quick-reference.md