tRPC vs GraphQL: API Architecture Comparison
tRPC provides end-to-end type safety for TypeScript full-stack apps with zero boilerplate, no schema files, and automatic type inference from your server functions. GraphQL is a query language for APIs with powerful tooling, excellent for exposing flexible data to multiple clients or building public APIs. tRPC is the better default for TypeScript monorepos. GraphQL is better for public APIs or apps with multiple diverse clients.
Last updated: 2026-03
In This Comparison
72% of organisations have adopted AI in at least one business function
Source: McKinsey 2025
40-60% reduction in operational costs with AI automation
Source: McKinsey 2025
Side-by-Side Comparison
| Category | trpc | graphql |
|---|---|---|
| Best For | TypeScript monorepos | Flexible APIs |
| Learning Curve | Easy | Medium |
| Type Safety | Automatic | With codegen |
| Client Control | Limited | Excellent |
| Ecosystem | Growing | Huge |
| Setup | Minimal | More setup |
| Public API | Not ideal | Excellent |
trpc
- Best For
- TypeScript monorepos
- Learning Curve
- Easy
- Type Safety
- Automatic
- Client Control
- Limited
- Ecosystem
- Growing
- Setup
- Minimal
- Public API
- Not ideal
graphql
- Best For
- Flexible APIs
- Learning Curve
- Medium
- Type Safety
- With codegen
- Client Control
- Excellent
- Ecosystem
- Huge
- Setup
- More setup
- Public API
- Excellent
Winner by Category
Best for Beginners
trpcLess boilerplate to learn
Best for Customisation
graphqlMore flexible queries
Best for Speed
trpcNo codegen step needed
Best for Learning
graphqlIndustry standard knowledge
Best Value
TieBoth are open source
Our Recommendation
Use tRPC for full-stack TypeScript projects. Choose GraphQL for public APIs or when clients need query flexibility.
“The best tool depends on what you are building and how you work. There is no universal winner. Pick the one that fits your workflow and budget, then ship something.”
When to Choose Each Tool
Choose tRPC
Full-stack TypeScript projects
Choose GraphQL
Public APIs or multiple client types
tRPC vs GraphQL: Two Approaches to Type-Safe APIs
tRPC and GraphQL both aim to improve the developer experience of building APIs, but they solve the problem differently. GraphQL, developed by Facebook and released in 2015, is a query language that lets clients request exactly the data they need from a server. It uses a schema definition language, resolvers, and code generation to provide type safety across the API boundary.
tRPC, created by Alex Johansson in 2021, takes a radically simpler approach for TypeScript monorepos. It shares TypeScript types directly between server and client through the TypeScript compiler — no schema language, no code generation, no runtime overhead. You define server functions (procedures), and the client gets fully typed access to those functions automatically.
The trade-off is scope. GraphQL works across any language and any client — web, mobile, third-party integrations. tRPC works only in TypeScript monorepos where server and client share a codebase. GraphQL is a communication protocol; tRPC is a TypeScript library. Choosing between them depends primarily on whether your clients and server share a TypeScript codebase.
Type Safety: tRPC's Zero-Configuration Advantage
tRPC's type safety is effortless. Define a procedure on the server with Zod input validation, and the client automatically knows the input types, output types, and error types — with zero configuration. Change a field name on the server, and TypeScript immediately flags every client call that uses the old name. This feedback loop is instant and requires no build step.
GraphQL's type safety requires additional tooling. You write a GraphQL schema, implement resolvers, then run a code generation step (typically graphql-codegen) to produce TypeScript types from the schema. These generated types are used in client queries. The type safety is excellent once configured, but the setup involves multiple tools, configuration files, and a code generation step that must run whenever the schema changes.
The practical impact is significant for developer velocity. With tRPC, refactoring an API endpoint is a standard TypeScript rename operation. With GraphQL, it involves updating the schema, regenerating types, and updating all queries that reference the changed field. For teams iterating rapidly on their API, tRPC's zero-overhead type safety eliminates friction that GraphQL's toolchain introduces.
Setup and Boilerplate
tRPC setup in a TypeScript monorepo is minimal. Install the packages, create a router with procedures, and initialise the client. A basic tRPC setup might be 50 lines of code. There is no schema file, no resolvers file, no code generation configuration, and no build step beyond your existing TypeScript compilation. Adding a new endpoint is writing a function.
GraphQL setup requires more infrastructure. You need a GraphQL server (Apollo Server, Yoga, Mercurius), a schema definition (SDL or code-first), resolver implementations, and client-side tooling (Apollo Client, urql, or similar). For type safety, add graphql-codegen with its configuration file. A basic GraphQL setup might be 200-300 lines across multiple files, plus configuration for code generation.
This complexity difference matters most at the start of a project and when onboarding new developers. tRPC's simplicity means a new developer can understand the full API layer in minutes. GraphQL's architecture — schemas, resolvers, data loaders, code generation — requires more learning time. For small teams moving fast, tRPC's minimal boilerplate is a significant velocity advantage.
Client Flexibility: GraphQL's Strength
GraphQL's query language lets clients request exactly the data they need. A mobile client might request a user's name and avatar, while a web dashboard requests the full user profile with activity history. Both use the same API endpoint but receive different response shapes. This flexibility reduces over-fetching (receiving unneeded data) and under-fetching (needing multiple requests for related data).
tRPC procedures return fixed response shapes. If you need different data subsets for different clients, you either create separate procedures or return the full data and let the client ignore unused fields. This is perfectly acceptable when you have one or two client applications in the same monorepo, but becomes wasteful when multiple diverse clients consume the same API.
For public APIs consumed by third-party developers, GraphQL's flexibility is essential — you cannot predict what data external clients will need. For internal APIs in TypeScript monorepos with a small number of known clients, tRPC's fixed responses are simpler and the over-fetching is negligible. The client flexibility question largely maps to whether your API is public or internal.
Performance and Runtime Overhead
tRPC has virtually no runtime overhead. Procedure calls are standard HTTP requests (or WebSocket messages for subscriptions) with JSON payloads. There is no schema parsing, no query validation, no resolver tree traversal. The server receives a request, runs the procedure function, and returns the result. The simplicity translates to lower latency and reduced server resource consumption.
GraphQL introduces runtime overhead from query parsing, validation against the schema, and resolver tree execution. Each GraphQL query is parsed from a string, validated against the schema definition, and executed by traversing the resolver tree. Data loader patterns (batching N+1 queries) add complexity but improve database performance. For simple queries, this overhead is measurable but small (1-5ms). For complex nested queries, resolver orchestration can add meaningful latency.
In practice, the performance difference is rarely the deciding factor. Network latency, database query time, and business logic execution dominate request duration. GraphQL's resolver overhead is measurable in benchmarks but negligible in production for most applications. tRPC's simpler execution model does provide marginally lower baseline latency, which compounds at very high request volumes.
Ecosystem and Tooling
GraphQL has a massive ecosystem developed over nearly a decade. Apollo Client provides sophisticated caching, optimistic updates, and pagination. GraphiQL and Apollo Studio provide interactive query explorers. Hasura and PostGraphile generate GraphQL APIs from databases automatically. The ecosystem includes tools for schema stitching, federation (combining multiple GraphQL services), and performance monitoring.
tRPC's ecosystem is smaller but growing rapidly within the TypeScript community. It integrates natively with React Query (TanStack Query) for client-side data management, providing caching, background refetching, and optimistic updates. The T3 Stack (Next.js + tRPC + Prisma + Tailwind) has popularised tRPC as part of a cohesive TypeScript stack. tRPC also supports subscriptions via WebSockets and server-sent events.
For advanced API patterns — federation across microservices, automatic API generation from databases, or serving diverse client types — GraphQL's ecosystem is substantially richer. For TypeScript monorepo applications with straightforward API needs, tRPC's ecosystem provides everything required with less tooling overhead.
Our Recommendation: tRPC for Monorepos, GraphQL for Everything Else
Choose tRPC if your project is a TypeScript monorepo where server and client share a codebase. The zero-configuration type safety, minimal boilerplate, and rapid development velocity make tRPC the superior choice for this architecture. Most Next.js applications, T3 Stack projects, and single-team TypeScript products fall into this category.
Choose GraphQL if your API serves multiple diverse clients (web, mobile, third-party), if your backend is not TypeScript, if you need federation across microservices, or if you are building a public API. GraphQL's flexibility, language independence, and ecosystem depth make it the right choice for these scenarios.
Do not choose GraphQL for a TypeScript monorepo just because it is more popular or because you want to learn it. The additional complexity of schemas, resolvers, and code generation provides no benefit when tRPC's type sharing achieves better type safety with less effort. Conversely, do not choose tRPC for a multi-language microservices architecture — it is designed specifically for TypeScript monorepos and does not extend beyond that context.
Frequently Asked Questions
Can tRPC work with non-TypeScript clients?
Not effectively. tRPC's type safety depends on sharing TypeScript types between server and client. Non-TypeScript clients can call tRPC endpoints as standard HTTP requests, but they lose the automatic type safety that is tRPC's primary benefit.
Is tRPC faster than GraphQL?
tRPC has marginally lower runtime overhead because it skips query parsing and resolver tree traversal. In practice, the performance difference is negligible for most applications — database queries and network latency dominate request duration.
Can I migrate from GraphQL to tRPC?
Yes, if your project is a TypeScript monorepo. Replace GraphQL resolvers with tRPC procedures and update client queries to tRPC calls. The migration is incremental — you can run both alongside each other during transition.
Does tRPC support real-time subscriptions?
Yes. tRPC supports subscriptions via WebSockets and server-sent events. The subscription API follows the same type-safe pattern as queries and mutations, with automatic TypeScript inference on the client.
Which is better for a public API?
GraphQL is better for public APIs. Its query language lets third-party developers request exactly the data they need without you predicting every use case. tRPC is designed for internal APIs in TypeScript monorepos, not public consumption.
Does tRPC work with Next.js App Router?
Yes. tRPC integrates with Next.js App Router through server-side callers and React Server Components. The integration allows calling tRPC procedures directly in server components without client-side fetching, combining tRPC's type safety with Next.js's rendering model.
Master Both Tools at buildDay Melbourne
Join our hands-on workshop and learn to build with the modern AI development stack. Go from idea to deployed app in a single day.