What Is tRPC?
Why type-safe APIs beat REST for TypeScript full-stack teams
Written by the RadarTrek editorial team · June 2026
If you have ever typed a field name into a fetch() call and wondered "does the backend actually return this?"— tRPC was built to eliminate that question. It lets you call server-side functions from the client with the same type safety you get calling a local function. No REST, no GraphQL schema, no code generation step. Just TypeScript.
The problem tRPC solves
In a typical full-stack TypeScript project, a disconnect exists between server and client. The backend defines a route that returns { userId: string; email: string }. The frontend guesses at that shape and writes it by hand. When the backend renames userId to id, the frontend breaks at runtime — not at build time. You only find out when a user hits that page.
- No shared types by default — REST and fetch() return unknown. You cast it manually and hope the shape matches what the server sends.
- Schema duplication — With OpenAPI or GraphQL, you write a schema on the server and generate types on the client. That is two places to keep in sync.
- Runtime surprises — Type errors in API contracts surface in production, not during development. TypeScript cannot help you across an HTTP boundary — unless something bridges that gap.
What tRPC actually is
tRPC is a TypeScript library that lets you define typed procedures on the server and call them from the client as if they were local async functions. The type information flows end-to-end through TypeScript's type inference — no runtime overhead, no generated files, no separate schema language.
tRPC is like removing the HTTP layer from your mental model
Imagine you could just import a function from your server file and call it in your React component. You would get autocomplete, type errors, and refactoring support automatically. That is what tRPC feels like — the network call is still there, but TypeScript acts as if it is not. The analogy breaks down at runtime (HTTP does exist), but for developer experience, it is the closest thing to server functions in a client component.
tRPC vs REST vs GraphQL
- REST — URL-based, any client can call it, no type safety across the wire. Best for public APIs consumed by unknown clients.
- GraphQL — Flexible query language, schema as the contract, code generation required. Best when clients have widely varying data needs (e.g. mobile vs web vs third parties).
- tRPC — TypeScript-only, zero schema maintenance, instant type safety. Best when client and server are both TypeScript and live in the same repo (monorepo or Next.js).
When to choose tRPC
The right tool for the right job
tRPC shines in full-stack TypeScript projects where the client and server are co-located — especially Next.js apps. If you need a public API consumed by mobile apps, third-party developers, or non-TypeScript clients, REST or GraphQL is a better fit. tRPC is not trying to replace those — it is solving a specific problem for a specific audience.
Core concepts at a glance
- Router — A collection of procedures grouped by feature (e.g. userRouter, postRouter). Routers compose into an app router.
- Procedure — A single typed endpoint — either a query (reads data) or a mutation (writes data). Procedures optionally accept Zod-validated input.
- Context — A per-request object injected into every procedure. Holds your database client, session, user, etc.
- Middleware — A function that runs before a procedure. Used for auth checks, rate limiting, logging.
- Client — A thin wrapper generated from your router type. Gives you autocomplete for every procedure name and input shape.
Key ideas from this lesson