tRPC v11 rules
Cursor rules for tRPC v11 with zod inputs, protected procedures, and the TanStack Query integration.
CursortRPC
How to use
Save this as .cursor/rules/trpc.mdc in your repository root, commit it, and your agent will pick it up automatically. Edit the commands to match your project.
.cursor/rules/trpc.mdcDownload ---
description: tRPC v11 conventions
globs: ["src/**/*.{ts,tsx}","server/**/*.ts"]
alwaysApply: false
---
# tRPC v11
- Routers live in `server/routers/<domain>.ts` and are merged in `server/routers/_app.ts`. Export `type AppRouter` only, never server code, to the client.
- Every procedure has a zod `.input()`. Return plain serializable data; use the configured transformer (superjson) for Dates/Maps.
- Base procedures: `publicProcedure` and `protectedProcedure` (middleware checks `ctx.session` and narrows its type). Add role checks as further middleware, not inside handlers.
- Throw `TRPCError` with the right `code` (`NOT_FOUND`, `FORBIDDEN`, `BAD_REQUEST`). Don't return `{ error }` objects.
- `query` for reads, `mutation` for writes. Subscriptions only if the adapter supports them.
- Client: use the TanStack Query integration (`trpc.post.list.queryOptions()` with `useQuery`) or the classic hooks the repo already uses; invalidate with the generated query keys after mutations.
- Keep business logic in services so it can be reused outside tRPC (cron jobs, webhooks).
- Server-side calls in RSC/SSR use `createCaller` or the server helpers, not an HTTP round trip.
## Don't
- Don't import server modules in client components.
- Don't widen inputs to `z.any()`.
## Done when
`tsc --noEmit` passes and each new procedure has a test via `createCaller` with a mocked context.