✓ Recommended
tRPC End-to-End Type Safety
tRPC for fully type-safe APIs between TypeScript client and server with zero codegen.
CLAUDE.md
# tRPC End-to-End Type Safety
You are an expert in tRPC, TypeScript, and end-to-end type-safe APIs.
Server Setup:
- Define router with `router()` and procedures with `publicProcedure` or `protectedProcedure`
- Input validation with Zod: `.input(z.object({ id: z.string() }))`
- Use `query` for reads, `mutation` for writes, `subscription` for real-time
- Nest routers for organization: `appRouter = router({ user: userRouter, post: postRouter })`
- Export type: `export type AppRouter = typeof appRouter` — this powers client inference
Middleware:
- Create reusable middleware with `t.middleware()`
- Auth middleware: check session, attach user to context
- Logging middleware: wrap procedure with timing/error tracking
- Chain middleware: `protectedProcedure = publicProcedure.use(isAuth).use(logAccess)`
- Access context in procedures: `ctx.user`, `ctx.db`, `ctx.session`
Client Usage (React):
- Use `@trpc/react-query` — wraps TanStack Query with type inference
- Query: `const { data } = trpc.user.getById.useQuery({ id: '123' })`
- Mutation: `const mutation = trpc.user.create.useMutation()`
- Invalidate after mutation: `utils.user.getAll.invalidate()`
- Optimistic updates: pass `onMutate` to mutation with cache manipulation
- Infinite queries: `trpc.post.list.useInfiniteQuery({ limit: 20 })`
Error Handling:
- Throw `TRPCError` with HTTP-like codes: `throw new TRPCError({ code: 'NOT_FOUND' })`
- Client receives typed errors — handle with `onError` or `error` property
- Use error formatting for consistent error shapes across all procedures
- Zod validation errors are automatically formatted with field-level details
Advanced Patterns:
- Use `createCallerFactory()` for server-side procedure calls (testing, cron jobs)
- Batch requests automatically — multiple queries in one HTTP request
- Use subscriptions with WebSocket adapter for real-time features
- Output validation with `.output(schema)` for runtime safety
- Use `experimental_caller` for edge runtimes (Cloudflare Workers, Deno)
Add to your project root CLAUDE.md file, or append to an existing one.