Das klassische Problem moderner Web-Entwicklung: Der Server liefert Daten zurück, aber der Client weiß zur Laufzeit nicht, wie diese Daten aussehen. REST-APIs erfordern manuelle Typdefinitionen, GraphQL braucht einen Schema-Layer und anschließend Code-Generierung. tRPC löst dieses Problem auf elegante Weise – indem es die API-Schicht schlicht abschafft und Server- und Client-Code als eine einzige TypeScript-Einheit behandelt.
Was ist tRPC?
tRPC steht für TypeScript Remote Procedure Call und ist ein Framework für Full-Stack-Anwendungen, bei dem Server und Client dieselbe TypeScript-Codebasis teilen. Das bedeutet: Wenn sich ein Rückgabetyp auf dem Server ändert, weiß der TypeScript-Compiler im Client sofort davon – noch bevor der Browser die Seite lädt. Es gibt keine Schemas, keine Code-Generierung und kein manuelles Synchronisieren von Typdefinitionen.
tRPC wurde von Alex Johansson entwickelt und ist Teil des populären T3-Stack, einer opinionierten Kombination aus Next.js, tRPC, Prisma, Tailwind CSS und NextAuth. Der T3-Stack hat maßgeblich zur Verbreitung von tRPC beigetragen und gilt als de-facto-Standard für TypeScript-Web-Projekte.
Router und Prozeduren
Das zentrale Konzept in tRPC sind Prozeduren. Eine Prozedur ist eine typisierte Funktion auf dem Server, die vom Client aufgerufen werden kann. Es gibt drei Arten:
- Query – für lesende Operationen (entspricht GET in REST)
- Mutation – für schreibende oder verändernde Operationen (entspricht POST/PUT/DELETE)
- Subscription – für Echtzeit-Updates über WebSockets oder Server-Sent Events
Prozeduren werden in Routern gruppiert. Router können verschachtelt werden, was eine saubere Strukturierung großer APIs ermöglicht. Der Root-Router des Servers wird anschließend als TypeScript-Typ exportiert und im Client-Code importiert. Durch TypeScripts strukturelles Typsystem fließen alle Typ-Informationen automatisch in den Client.
Queries und Mutations im Detail
Eine Query wird auf dem Client mit trpc.user.getById.useQuery({ id: 1 }) aufgerufen. tRPC nutzt im Hintergrund TanStack Query (früher React Query) für Caching, Refetching und Ladezustandsmanagement. Das bedeutet: Entwicklerinnen und Entwickler bekommen alle Vorteile von TanStack Query kostenlos dazu, ohne zusätzliche Konfiguration.
Mutations funktionieren analog: trpc.user.create.useMutation() gibt eine Funktion zurück, die mit den validierten Eingabedaten aufgerufen werden kann. Auch hier fließen die Typen vom Server zum Client, sodass falsch typisierte Eingaben zur Compile-Zeit erkannt werden.
@trpc/next-Adapter und dem neuen createTRPCClient für Server Components lassen sich Daten serverseitig fetchen, ohne einen separaten API-Endpunkt aufzurufen – die Prozedur wird direkt auf dem Server ausgeführt.
Zod für Eingabevalidierung
tRPC integriert sich nahtlos mit Zod, der beliebtesten Schema-Validierungsbibliothek für TypeScript. Mit dem .input()-Modifier einer Prozedur wird ein Zod-Schema definiert, das eingehende Daten validiert. Zod inferiert daraus automatisch den TypeScript-Typ, sodass keine doppelte Typdefinition notwendig ist.
Neben Zod werden auch Valibot, Yup und andere Schema-Bibliotheken unterstützt. Die Validierung findet serverseitig statt und wirft bei ungültigen Eingaben einen strukturierten Fehler, den der Client typsicher behandeln kann.
Next.js-Integration
tRPC wurde mit Next.js im Sinn entwickelt. Die Integration erfolgt über einen API-Route-Handler, der den tRPC-Router exposed. Der gesamte Austausch läuft über HTTP, aber die Typen fließen durch den gemeinsamen TypeScript-Code. Die offizielle tRPC-Dokumentation für Next.js bietet ausführliche Anleitungen für Pages Router und App Router.
Vergleich: tRPC vs. REST vs. GraphQL vs. OpenAPI
| Ansatz | Typsicherheit | Code-Generierung | Lernkurve | Geeignet für |
|---|---|---|---|---|
| tRPC | Ende-zu-Ende (nativ) | Keine | Niedrig (TypeScript nötig) | Full-Stack TS, interne APIs |
| REST | Manuell oder via OpenAPI | Optional | Sehr niedrig | Öffentliche APIs, Multi-Client |
| GraphQL | Via Codegen (GraphQL Codegen) | Erforderlich | Hoch | Komplexe Datenstrukturen, Mobile |
| OpenAPI | Via Codegen (openapi-ts) | Erforderlich | Mittel | Öffentliche APIs, Multi-Sprachen |
Wann tRPC nicht die richtige Wahl ist
tRPC ist ein ausgezeichnetes Werkzeug – aber nur unter bestimmten Voraussetzungen. Es gibt klare Szenarien, in denen andere Ansätze besser passen:
Weitere Einschränkungen: tRPC setzt eine monorepo-ähnliche Struktur voraus, bei der Client und Server denselben TypeScript-Code importieren können. In strikt getrennten Repositories ist der Typ-Sharing-Mechanismus aufwendiger einzurichten. Auch bei Microservices mit vielen unabhängigen Teams ist GraphQL Federation oder eine OpenAPI-Spezifikation oft praktikabler.
Ökosystem und Community
tRPC hat eine sehr aktive Community, die auf GitHub über 35.000 Sterne gesammelt hat. Der Discord-Server ist gut besucht und Fragen werden schnell beantwortet. Zahlreiche Adapter für Astro, SolidStart, Svelte und andere Frameworks existieren als Community-Pakete.
Häufig gestellte Fragen
- Funktioniert tRPC ohne Next.js?
- Ja. tRPC ist framework-agnostisch. Es gibt offizielle Adapter für Express, Fastify und Fetch-basierte Server. Auch React ohne Next.js, Solid.js und andere Frontend-Frameworks werden unterstützt.
- Wie groß ist der Bundle-Overhead durch tRPC auf dem Client?
- Das
@trpc/client-Paket ist sehr schlank (~5 KB gzip). Der Großteil des Codes läuft serverseitig. TanStack Query, das optional eingebunden wird, fügt weitere ca. 13 KB hinzu – aber dieses Package liefert umfangreiches Caching und ist den Overhead in den meisten Projekten wert. - Kann ich tRPC mit einer bestehenden REST-API kombinieren?
- Ja. tRPC und REST können nebeneinander betrieben werden. Es ist möglich, tRPC schrittweise in eine bestehende Anwendung einzuführen und neue Endpunkte als tRPC-Prozeduren zu implementieren, während alte REST-Endpunkte bestehen bleiben.
- Unterstützt tRPC Authentifizierung und Autorisierung?
- tRPC hat ein Middleware-System, über das Authentifizierungslogik zentral implementiert werden kann. Mit
protectedProcedurelassen sich Prozeduren absichern, die nur für eingeloggte Nutzerinnen zugänglich sind – eine gängige Praxis im T3-Stack mit NextAuth.