tRPC

tRPC

End-to-end type-safe APIs without code generation

Features

  • End-to-end type safety from server to client
  • No code generation or build step required
  • Automatic type inference with Zod validation
  • Framework-agnostic with adapters for Next.js, Express, Fastify, etc.

Pros

  • Eliminates API contract mismatches entirely
  • Incredible DX with autocompletion across the stack
  • Lightweight — just TypeScript, no extra tooling

Cons

  • TypeScript-only (both client and server must be TS)
  • Tightly couples frontend and backend code
  • Not suitable for public APIs consumed by third parties

Overview

tRPC enables you to build fully type-safe APIs without schemas, code generation, or runtime overhead. By leveraging TypeScript’s type inference, tRPC shares types directly between your server and client, so any change to an API procedure immediately shows type errors in the client code.

Unlike REST or GraphQL, tRPC doesn’t require you to define contracts separately. You write your server procedures with Zod validation, and the client automatically knows the input and output types. This makes it the fastest way to build internal APIs for full-stack TypeScript applications.

When to Use

tRPC is perfect for full-stack TypeScript monorepos where the same team owns both frontend and backend. It’s ideal for internal APIs where type safety matters more than cross-language compatibility. For public APIs, REST or GraphQL is more appropriate.

Getting Started

npm install @trpc/server @trpc/client zod
import { initTRPC } from "@trpc/server";
import { z } from "zod";

const t = initTRPC.create();

const appRouter = t.router({
  greeting: t.procedure
    .input(z.object({ name: z.string() }))
    .query(({ input }) => `Hello ${input.name}`),
});

export type AppRouter = typeof appRouter;