What is tRPC?
tRPC lets a TypeScript client call server procedures as if they were local functions, with full type safety and no code generation. The types flow from server to client automatically, so a change to a procedure's input or output is a compile error on the client. It shines in full-stack TypeScript apps.
Why it matters
When the same team owns the frontend and backend in TypeScript, tRPC removes a whole class of bugs — mismatched request shapes, stale client types, manual validation — with zero schema duplication. It is increasingly common in Next.js stacks, so it is worth knowing where it fits and where it does not.
What to learn
- Procedures: queries vs mutations
- Input validation with a schema library like Zod
- How types flow from server to client without generation
- Routers and merging them
- Context for auth and per-request data
- When tRPC fits and when a public REST or GraphQL API is better
- Error handling across the boundary
Common pitfall
Reaching for tRPC for a public API consumed by third parties or non-TypeScript clients. Its whole advantage is shared TypeScript types across one codebase. For external consumers you want a documented, language-agnostic contract — REST with OpenAPI or GraphQL — not tightly coupled TypeScript inference.
Resources
Primary (free):
- tRPC — Documentation · docs
- Zod — Documentation · docs
- tRPC — Quickstart · docs
Practice
Add a tRPC router with one query and one mutation, validating input with Zod. Call both from a TypeScript client and confirm that changing a procedure's input type produces a compile error on the client before you ever run it. Done when the type error appears at build time.
Outcomes
- Define typesafe queries and mutations with validated input.
- Explain how types reach the client without code generation.
- Add per-request context for auth.
- Decide when tRPC fits versus a public REST or GraphQL API.