The seamAdvanced6h

Contracts with tRPC.

Typesafe client-server calls with no schema duplication.

What is tRPC?

tRPC lets the client call server procedures as if they were local functions, with full type safety and no code generation or separate schema language. The procedure's input and output types flow straight to the client, so the contract is the code itself.

Why it matters

tRPC is the purest expression of the TypeScript full-stack seam: change a procedure's signature and the client gets a compile error instantly, with no REST boilerplate or schema duplication. For a TypeScript monorepo where one team owns both ends, it removes a whole layer of friction and bugs.

What to learn

  • Procedures: queries and mutations
  • Input validation with Zod
  • How types reach the client without generation
  • Routers and merging them
  • Context for per-request data like the user
  • Integrating tRPC with TanStack Query
  • When REST or GraphQL is the better choice

Common pitfall

Choosing tRPC for an API that public or non-TypeScript clients must consume. Its whole advantage is shared TypeScript inference within one codebase; external consumers need a language-agnostic, documented contract — REST with OpenAPI or GraphQL. Use tRPC for your own client, not as a public API.

Resources

Primary (free):

Practice

Build a tRPC router with one query and one mutation, validating input with Zod and reading the user from context. Call both from a typed client. Change a procedure's input type and watch the client fail to compile. Done when the contract is enforced by types with zero duplication.

Outcomes

  • Define typesafe queries and mutations with validated input.
  • Explain how types reach the client without generation.
  • Add per-request context like the authenticated user.
  • Choose tRPC versus REST/GraphQL appropriately.
Back to Full-Stack roadmap