tRPC vs GraphQL 2026: Which API Layer Should You Actually Use?
tRPC wins for full-stack TypeScript monorepos where speed of iteration matters most; GraphQL wins for multi-client, multi-team APIs that need flexible querying. Pick based on your client diversity, not just your language preference.
Choosing between tRPC and GraphQL in 2026 is really a question about who your API is for. If it only ever speaks to your own TypeScript frontend, tRPC is a force multiplier — zero schema files, zero codegen, just types flowing end-to-end. If your API needs to serve iOS apps, partner integrations, a public developer portal, or teams working in Python and Go, GraphQL's explicit schema contract is worth every extra kilobyte. The short verdict: tRPC for internal TypeScript monorepos, GraphQL for multi-client or multi-language ecosystems — and the rest of this guide explains exactly where that line sits.
Choose between tRPC and GraphQL based on your client diversity, not your language preference: tRPC for internal TypeScript monorepos, GraphQL for multi-client ecosystems.
The Headline Differences
| Dimension | tRPC | GraphQL |
|---|---|---|
| Type Safety | End-to-end, inferred from server | Schema-driven; codegen required |
| Language Support | TypeScript / JS only | Language-agnostic (30+ SDKs) |
| Client Flexibility | One TypeScript client | Any client, any language |
| Schema / Contract | Implicit (TypeScript types) | Explicit SDL schema |
| Setup Complexity | Low — install & go | Medium — schema + resolvers + codegen |
| Network Protocol | HTTP + WebSockets (native) | HTTP, WS, HTTP/2 — varies by impl |
| Bundle Size Impact | Minimal (~2 KB client lib) | Larger (Apollo Client ~30 KB+) |
| Subscriptions | Built-in via WebSockets | Built-in (requires WS transport) |
| Caching Strategy | Manual / react-query built-in | Normalized (Apollo, Relay, urql) |
| Ecosystem / Tooling | Growing; T3 Stack popular | Mature; Apollo, Hasura, Relay |
| Best-Fit Team Size | Small–medium, single codebase | Medium–large, multi-team/client |
| License | MIT | MIT (spec); varied per impl |
These two tools solve adjacent problems but make very different bets on how teams build software:
- Type safety mechanism: tRPC infers types directly from your router definition — no separate schema, no codegen step, no drift. GraphQL types live in a
.graphqlSDL file and require a code generation pipeline (graphql-codegen, Pothos, etc.) to surface in TypeScript. - Client diversity: tRPC generates a single, tightly-coupled TypeScript client. GraphQL clients exist for every mainstream language. If a mobile engineer or a data scientist needs to query your API, GraphQL wins immediately.
- Schema explicitness: GraphQL's SDL is a living contract you can version, lint, and share publicly. tRPC's "schema" is your TypeScript source — powerful for a single team, opaque to outsiders.
- Bundle weight: The tRPC client adds roughly 2 KB to a frontend bundle. Apollo Client adds upward of 30 KB; lighter clients like urql or graphql-request bring that closer to 8–12 KB.
- Caching sophistication: Apollo and Relay offer normalized, entity-level caching out of the box. tRPC delegates caching to TanStack Query (react-query), which is request-level.
- Subscriptions & real-time: Both support WebSocket-based subscriptions natively, though tRPC's approach is simpler to wire up in a Next.js or tRPC-native stack.
- Ecosystem maturity: GraphQL turned 10 in 2025 and has a vast constellation of tools — Hasura, StepZen, Apollo Studio, Relay. tRPC (v11 at the time of writing) is younger but growing rapidly, particularly inside the T3 Stack community.
When tRPC Wins
Full-Stack TypeScript Teams Moving Fast
tRPC is purpose-built for the scenario where the same engineer — or the same small team — writes both the API and the client. You define a router in your backend, and TypeScript automatically knows what procedures exist, what arguments they accept, and what they return. No .graphql file, no yarn codegen, no out-of-sync types discovered at runtime. The feedback loop collapses.
Consider a startup building a SaaS product with Next.js, Prisma, and a single web frontend. With tRPC, a developer adds a new getSubscriptionStatus procedure on the server, and the frontend immediately gets autocomplete and compile-time safety — no intermediate step. That's a genuine productivity gain that compounds across hundreds of PRs.
Where tRPC especially shines:
- T3 Stack projects: create-t3-app scaffolds tRPC, Prisma, NextAuth, and Tailwind together. The entire surface area is TypeScript, and tRPC fits perfectly.
- Internal tooling and dashboards: Admin panels, internal analytics boards, and back-office tools rarely need multi-language clients. tRPC gives you type safety without the overhead of a GraphQL layer.
- Rapid prototyping: When you're iterating on API shape frequently, not having to update a schema file and rerun codegen saves meaningful time per cycle.
- Monorepos with shared types: tRPC's router types can live in a shared
packages/apiworkspace, making full-stack type sharing trivial with tools like Turborepo or Nx.
Performance considerations: Because tRPC procedures map directly to HTTP endpoints (GET or POST by convention), there's no query parsing overhead at runtime. Each call hits a specific handler rather than a general-purpose query engine. In latency-sensitive internal tools, this matters — think of it like the principle explored in I Tested 5 LLM APIs for Latency — Here's the Real Data (March 2026): raw protocol overhead compounds when you're chaining calls.
The ceiling: tRPC's TypeScript-only constraint is a hard wall. The moment a non-TypeScript client needs to consume your API — a React Native app written in JS without strict TypeScript, a Python ML service, a third-party webhook consumer — you're either maintaining a parallel REST layer or you've outgrown tRPC as a sole transport.
When GraphQL Wins
Multi-Client, Multi-Team, or Public APIs
GraphQL was designed to solve a problem that Facebook had in 2012: dozens of clients (iOS, Android, web, third-party) needing different shapes of the same underlying data, without the API team shipping a new REST endpoint for every permutation. That problem hasn't gone away, and GraphQL remains the best structural answer to it in 2026.
Specific scenarios where GraphQL is the right call:
- Mobile + web clients: iOS and Android apps frequently need different field subsets than a web app. GraphQL's projection (selecting only needed fields) reduces over-fetching, which matters on constrained mobile connections. Apollo iOS and Apollo Kotlin are mature, production-hardened clients.
- BFF (Backend for Frontend) replacement: GraphQL can replace multiple BFF layers by letting each client declare exactly what it needs — no custom endpoint proliferation.
- Partner and public APIs: Stripe, GitHub, and Shopify all expose public GraphQL APIs. When external developers need to explore your API, GraphQL's introspection and tooling (GraphiQL, Apollo Sandbox) provide a self-documenting experience that tRPC simply can't match.
- Complex data graphs: If your domain model has deeply nested relationships — users → organizations → projects → tasks → comments — GraphQL's resolver chain handles arbitrary depth elegantly. Clients can traverse the graph without the server pre-defining every join shape.
- Polyglot microservices: Apollo Federation lets multiple backend services (written in Node.js, Go, Java, Python) each own a subgraph of the schema, stitched into a unified supergraph. tRPC has no equivalent concept.
Caching advantage: Apollo Client's normalized cache de-duplicates entity data across queries. If a User:42 object appears in five different query results, it's stored once and updated atomically. This is architecturally significant for large apps where UI consistency matters.
Tooling depth: Apollo Studio offers schema change detection, field usage analytics, and performance tracing. These observability features are critical for teams managing schemas used by external consumers. The maturity gap here is real — GraphQL's ecosystem has had a decade to accumulate production tooling that tRPC's ecosystem is still building.
The ceiling: GraphQL's verbosity and setup cost are real. A simple CRUD API in tRPC takes 30 minutes; the same in GraphQL (schema, resolvers, codegen config, Apollo Server setup) takes considerably longer. For teams that never need client diversity, that overhead buys nothing. Also worth noting: GraphQL's flexibility can create N+1 query problems that require DataLoader or similar batching solutions — an additional complexity tRPC avoids entirely.
Performance & Latency
Raw HTTP performance between tRPC and GraphQL is rarely the deciding factor, but the differences are worth understanding. tRPC's procedure calls translate to simple HTTP POST requests — the server executes a known handler, serializes the result, and returns. There's no query parsing, no AST traversal, no field resolver chain. For simple fetch patterns, tRPC is measurably leaner.
GraphQL adds query parsing and validation on every request unless you implement persisted queries (APQ). APQ hashes queries at build time so the server receives a hash rather than a full query string, recovering most of the parsing overhead. With APQ enabled, the latency gap between GraphQL and tRPC narrows significantly.
The bigger performance difference is over-fetching. REST and tRPC return the full procedure output — if you add 10 fields to a response and only 3 are used by the client, you're wasting bandwidth. GraphQL clients specify exactly what fields they need, which matters at scale with large response objects or mobile clients on constrained networks.
Subscription performance is roughly equivalent — both use WebSockets with similar server overhead. tRPC uses a simple JSON-RPC style message format; GraphQL uses the graphql-ws protocol, which adds a small amount of message framing overhead but is negligible in practice.
Verdict on performance: For request-response workloads with a TypeScript client, tRPC wins on latency. For large-payload APIs consumed by bandwidth-constrained clients, GraphQL's selective projection wins on total data transferred. See also the performance analysis approach in [Rust WASM vs TypeScript Performance: Why the 'Faster' Language Lost by 25% [2026]](/blog/rust-wasm-vs-typescript-performance) — the "faster" tool on paper doesn't always win in production context, and the same nuance applies here.
Setup Complexity & Developer Experience
tRPC Setup
A minimal tRPC v11 setup in a Next.js App Router project:
1. npm install @trpc/server @trpc/client @trpc/react-query @tanstack/react-query zod
2. Define your appRouter in server/trpc.ts with Zod-validated inputs.
3. Mount the handler in app/api/trpc/[trpc]/route.ts.
4. Create a typed client in utils/trpc.ts.
That's it. No schema file. No codegen script. Types flow automatically. A developer new to the stack can be productive in under an hour, and the official tRPC docs are remarkably concise given the capability on offer.
GraphQL Setup
A production GraphQL setup involves more moving parts:
1. Install Apollo Server (or Yoga, Mercurius, etc.) + graphql package.
2. Write your SDL schema or use a code-first builder like Pothos or TypeGraphQL.
3. Write resolver functions for every field.
4. Set up graphql-codegen with a config file to generate TypeScript types from the schema.
5. Configure a client (Apollo Client, urql, or graphql-request) on the frontend.
6. (Optional but recommended) Set up Apollo Studio or a local GraphiQL instance.
The gap in initial setup time is real — roughly 30–60 minutes for tRPC vs. 2–4 hours for a well-configured GraphQL stack. However, the GraphQL setup cost is largely a one-time investment. Once the pipeline is established, adding new types and resolvers is incremental.
Codegen drift is the most common GraphQL DX complaint: the schema and generated types get out of sync when developers forget to rerun codegen. Tools like graphql-codegen --watch mitigate this, but it's a category of bug tRPC eliminates entirely by design.
Ecosystem Maturity & Long-Term Viability
GraphQL's ecosystem in 2026 is deep and battle-tested. The GraphQL Foundation (a Linux Foundation project) governs the spec, ensuring vendor neutrality. Apollo, The Guild (Yoga, Envelop, Codegen), Hasura, StepZen, and WunderGraph all build on the same open specification. Major cloud providers — AWS AppSync, Google Cloud's Apigee — offer managed GraphQL infrastructure. GitHub's v4 API, Shopify's Storefront API, and Meta's own internal infrastructure are all GraphQL. The technology has proven it can run at internet scale.
tRPC's ecosystem is younger but healthy. The T3 Stack adoption has driven significant community growth. The tRPC GitHub repository has accumulated over 34,000 stars (as of early 2026), and the package sees millions of weekly npm downloads. Version 11 brought first-class support for Next.js App Router and React Server Components, keeping pace with the framework ecosystem. The risk of tRPC being abandoned is low — it's deeply embedded in a popular stack — but it has fewer enterprise production case studies than GraphQL.
Integration with AI tooling: As AI-driven backends become more common (think LLM APIs, vector search endpoints, agentic workflows), both tRPC and GraphQL can serve as the transport layer. For teams building TypeScript-first AI features, tRPC pairs well with the emerging patterns described in The Complete Guide to Running Local LLMs in 2026. For teams building public AI APIs that external consumers will query, GraphQL's self-documenting schema is valuable.
Framework support: tRPC has first-class adapters for Next.js, SvelteKit, Nuxt, Fastify, Express, and AWS Lambda. GraphQL has implementations in every major server framework across every language. If there's any chance your backend language changes, GraphQL's language agnosticism is an insurance policy tRPC doesn't offer.
How to Choose Between Them
The decision comes down to three questions, asked in order:
1. Do all current and foreseeable clients speak TypeScript?
If yes — including any mobile apps (React Native with TypeScript counts), internal tools, and background services — tRPC is almost certainly the right choice. The productivity gains from automatic type safety are real and compounding. If any client is or will be in another language, skip to question 3.
2. Is your team small and does it own both the API and the frontend?
tRPC's tight coupling is a feature, not a bug, when a single team controls both sides. If organizational boundaries mean different teams own the API and the clients, GraphQL's explicit schema contract serves as a better interface agreement — it's versionable, documentable, and consumable without access to the server source code.
3. Do you need client flexibility, public discoverability, or federated multi-service composition?
GraphQL wins on all three counts. Introspection makes GraphQL APIs self-documenting. Apollo Federation lets you compose a supergraph from microservices without a central orchestrator. If either of these is in your roadmap, starting with GraphQL avoids a migration later.
The honest middle ground: Many teams use both. tRPC handles internal, server-to-server TypeScript calls; a GraphQL layer exposes the public-facing or multi-client API. This hybrid isn't as exotic as it sounds — it's analogous to having internal RPC and external REST in a mature microservices architecture. The key is not treating the choice as permanent — both tools can coexist, and the right answer in year one may differ from year three.
Common Mistakes When Choosing Between tRPC and GraphQL
Mistake 1: Choosing GraphQL because it sounds more "serious"
GraphQL has a reputation for being the "grown-up" API choice, and some teams adopt it for status rather than need. If you have a TypeScript monorepo with one client, GraphQL adds genuine complexity with no payoff. The setup cost, codegen pipeline, and resolver overhead are real taxes that only make sense when you're collecting the multi-client dividend.
Mistake 2: Dismissing tRPC because "we'll need external clients eventually"
"Eventually" is doing a lot of work in this sentence. If external client needs are speculative, optimize for the current constraint (fast iteration) rather than the hypothetical one. tRPC procedures can be wrapped in a REST or GraphQL layer later if needed, and the Zod validation schemas you write today can inform a future GraphQL schema.
Mistake 3: Ignoring the N+1 problem in GraphQL
Teams that adopt GraphQL without understanding DataLoader often ship APIs with catastrophic N+1 query patterns — one database query per item in a list. tRPC doesn't have this problem by default because you control the exact data fetching in each procedure. GraphQL's resolver model requires deliberate batching design from day one.
Mistake 4: Assuming tRPC replaces all HTTP patterns
tRPC is an RPC layer, not a full HTTP framework. File uploads, webhooks, OAuth redirects, and streaming responses don't map cleanly to tRPC procedures. You'll still need plain HTTP handlers alongside tRPC for these patterns, just as you might with a framework-agnostic approach discussed in [Native Browser APIs That Make Your Frontend Framework Overkill [2026]](/blog/native-browser-apis-replace-frameworks) — sometimes the right layer is just the raw protocol.
Where to Go Deeper
If this comparison has you thinking about broader API and performance architecture decisions, several related deep-dives are worth your time:
- Language-level performance tradeoffs: [Rust WASM vs TypeScript Performance: Why the 'Faster' Language Lost by 25% [2026]](/blog/rust-wasm-vs-typescript-performance) — a reminder that theoretical speed advantages don't always survive contact with real workloads. The same caution applies when benchmarking tRPC vs. GraphQL in isolation.
- Latency measurement methodology: I Tested 5 LLM APIs for Latency — Here's the Real Data (March 2026) — rigorous latency testing methodology you can adapt for measuring your own tRPC vs. GraphQL API response times.
- AI-native backends: The Complete Guide to Running Local LLMs in 2026 — if your next API is a TypeScript-first AI service, tRPC's lean footprint pairs well with local inference infrastructure.
- Security considerations: The Complete Guide to AI Security in 2026 — both tRPC and GraphQL have unique attack surfaces (introspection abuse in GraphQL, unvalidated inputs in tRPC); this guide covers threat modeling for modern API stacks.
The tRPC vs. GraphQL decision is not a one-time, company-wide commitment. Evaluate it per service, per team topology, and per client landscape — and revisit as those constraints evolve.
Frequently Asked Questions
What is the main difference between tRPC and GraphQL?
tRPC is a TypeScript-only RPC framework that infers end-to-end types directly from your server router, requiring no schema file or codegen. GraphQL is a language-agnostic query language with an explicit SDL schema that any client in any language can consume. tRPC optimizes for developer speed in TypeScript monorepos; GraphQL optimizes for client flexibility and self-documentation in multi-team or multi-language environments.
Is tRPC faster than GraphQL?
tRPC is generally faster at the protocol level for simple request-response calls — there's no query parsing or AST validation overhead. However, GraphQL with Automatic Persisted Queries (APQ) closes most of that gap. GraphQL can outperform tRPC on bandwidth by allowing clients to select only the fields they need, which matters on mobile or high-traffic APIs. For most applications, the performance difference is negligible compared to database or network latency.
Can you use tRPC and GraphQL together?
Yes. A common pattern is using tRPC for internal TypeScript service-to-service communication and a GraphQL layer for external or multi-client APIs. The two are not mutually exclusive — tRPC handles the fast, type-safe internal calls while GraphQL provides the flexible, self-documenting external contract. Many mature TypeScript codebases run both transports simultaneously.
Should I use tRPC for a large-scale application?
tRPC scales well for large TypeScript monorepos where a single team or org controls both the API and its clients. The constraint is client diversity, not application size. If your large-scale app has multiple mobile clients, public API consumers, or teams working in non-TypeScript languages, GraphQL's explicit schema and federation capabilities are better suited. If it's TypeScript-only, tRPC can handle significant scale.
Does tRPC support subscriptions and real-time data?
Yes. tRPC v10+ supports subscriptions via WebSockets using its built-in WebSocket server adapter. You define a subscription procedure on the server and the typed client can subscribe to it just like any other procedure. The setup is simpler than GraphQL subscriptions, which require configuring a separate WebSocket transport and subscription server. Both approaches are production-ready for real-time use cases.
When should I choose GraphQL over tRPC in 2026?
Choose GraphQL when: (1) you have or plan to have non-TypeScript clients such as iOS, Android, or Python services; (2) you need a public or partner-facing API with introspection and self-documentation; (3) you're building a federated microservices architecture with Apollo Federation; or (4) different product teams own the API and the clients and need an explicit, versionable schema contract. For internal TypeScript apps, tRPC is usually the faster, simpler choice.
Kunal Ganglani (2026, May 10). tRPC vs GraphQL 2026: Which API Layer Should You Actually Use?. Kunal Ganglani. Retrieved August 13, 2026, from https://www.kunalganglani.com/blog/trpc-vs-graphql-2026


