Developer Toolsintermediate

tRPC vs GraphQL

A comparison of tRPC, the TypeScript-native way to build fully type-safe APIs without a separate schema language, and GraphQL, the schema-driven query language for building flexible, client-specified APIs.

Quick Answer

tRPC gives full end-to-end type safety directly from TypeScript function signatures with zero code generation or schema language, but only works within a single TypeScript codebase (client and server); GraphQL works across any language or client, with a formal schema and mature caching/tooling ecosystem, at the cost of more setup complexity than tRPC's minimal-ceremony approach.

Reviewed by TechLogHub Engineering Team. Last updated September 26, 2026. Reflects tRPC's continued growth as the default choice for full-stack TypeScript monorepos in 2026, alongside GraphQL's continued relevance for multi-language or public-facing APIs.

Feature comparison of tRPC vs GraphQL
FeaturetRPCGraphQL
Type Safety Approach
Automatic inference from TypeScript function signatures
Schema-driven, typically requires code generation for client types
Schema Language
None — plain TypeScript
GraphQL Schema Definition Language (SDL)
Code Generation Required
None required
Typically used (GraphQL Code Generator) for client type safety
Cross-Language Support
No — TypeScript client and server only
Yes — any language can be a client or server
Public API Suitability
Not designed for public/external consumption
Well-suited, formal schema as API contract
Caching/Tooling Ecosystem
React Query integration for client-side caching
Mature ecosystem (Apollo, Relay, various gateways)

tRPC

A TypeScript library for building fully type-safe APIs where the client automatically infers types directly from server-side function signatures, with no schema language, code generation step, or separate API contract to maintain.

Pros

  • End-to-end type safety with zero code generation — the client automatically infers exact types from server function signatures
  • No separate schema language to learn or maintain — it's just TypeScript functions, using types you already know how to write
  • Extremely fast iteration — changing a server function's signature immediately surfaces type errors on the client with no build step
  • Minimal setup ceremony compared to GraphQL's schema, resolvers, and query language
  • Excellent fit for full-stack TypeScript monorepos (Next.js, T3 stack) where both client and server share the same codebase

Cons

  • Only works within a single TypeScript codebase — client and server must both be TypeScript, ruling it out for cross-language APIs
  • Not designed for public, third-party-consumed APIs — there's no formal schema or documentation contract for external consumers
  • Smaller ecosystem of caching, tooling, and gateway infrastructure compared to GraphQL's much more mature surrounding tooling
  • Less established for very large-scale API surfaces spanning many independent teams or services compared to GraphQL's federation patterns

Best For

Full-stack TypeScript applications where the same team controls both client and server, particularly monorepo setups like the T3 stack, where type safety and iteration speed matter more than cross-language or public API support.

GraphQL

A schema-driven query language and runtime for building APIs that any client, in any programming language, can consume by specifying exactly the data they need against a formal, strongly-typed schema.

Pros

  • Language-agnostic — any client in any programming language can consume a GraphQL API, unlike tRPC's TypeScript-only constraint
  • Formal schema serves as a documented, versioned API contract suitable for public or third-party consumption
  • Mature, extensive tooling ecosystem for caching (Apollo Client), federation across multiple services, and API gateways
  • Well-established patterns for scaling API surfaces across many independent teams via schema federation
  • Not tied to any specific backend language — GraphQL servers exist for virtually every major programming language

Cons

  • More setup ceremony than tRPC — designing a schema, writing resolvers, and configuring the GraphQL server takes more upfront work
  • Type safety between client and server isn't automatic the way tRPC's inference is — typically requires a code generation step (GraphQL Code Generator) to derive TypeScript types from the schema
  • Steeper learning curve given its own query language and schema-first thinking, compared to tRPC's 'just write TypeScript functions' simplicity
  • For a single-team, single-language TypeScript application, GraphQL's cross-language flexibility is often unused overhead

Best For

APIs that need to be consumed across multiple languages or by third-party/public clients, larger organizations needing to federate an API surface across many independent teams, and any context where GraphQL's mature ecosystem tooling outweighs its extra setup complexity.

The Core Trade-off: Constraint for Simplicity

tRPC's central insight is that if you're already writing both the client and server in TypeScript within the same codebase, you don't need a separate schema language or code generation step at all — the TypeScript compiler itself can verify that the client is calling server functions correctly, with real-time type inference. This constraint (same-language, same-codebase) is exactly why tRPC can offer a simpler, more immediate developer experience than GraphQL, which is deliberately designed to work across language and codebase boundaries and therefore needs a formal schema as the shared contract.

When the Cross-Language Constraint Actually Matters

tRPC's TypeScript-only requirement is a hard constraint, not a minor inconvenience — if your API needs to be consumed by a mobile app written in Swift or Kotlin, a third-party integration partner, or any client not written in TypeScript, tRPC simply isn't an option. GraphQL's schema-first design means the same API can serve a TypeScript web client, a native mobile app, and external partners consistently, which is precisely the scenario where its additional setup complexity becomes clearly worth the investment.

Type Safety: Automatic vs Generated

tRPC's type safety is genuinely automatic — there's no build or generation step; changing a server function's return type immediately shows a TypeScript error on any client code using it, since the types are inferred directly and live. GraphQL typically achieves client-side type safety through a separate code generation step (tools like GraphQL Code Generator) that reads the schema and produces TypeScript types, which works well but introduces a build step and a moment of potential staleness between schema changes and regenerated types that tRPC's live inference avoids entirely.

Ecosystem Maturity Favors GraphQL at Larger Scale

GraphQL's much longer establishment has produced a mature ecosystem of caching solutions (Apollo Client's normalized cache), federation patterns for splitting a schema across many independent backend services owned by different teams, and API gateway tooling. tRPC's simpler model doesn't need most of this machinery for its target use case (single-team, single-codebase TypeScript apps), but that also means it doesn't offer comparable solutions if a project's needs grow beyond that scope — organizations anticipating significant API surface growth across many teams often find GraphQL's established federation patterns a better long-term fit.

Verdict

Choose tRPC for full-stack TypeScript applications where the same team owns both client and server, especially monorepo setups — its automatic end-to-end type safety with zero code generation is a genuinely superior developer experience for that specific, common scenario. Choose GraphQL when your API needs to be consumed across multiple languages, by third-party or public clients, or needs to scale across many independent teams via schema federation — capabilities tRPC deliberately doesn't attempt to provide.

All Comparisons

tRPC vs GraphQL — FAQ

Common questions answered from the comparison above

Can I use tRPC if my mobile app is written in Swift or Kotlin?

No — tRPC's core value proposition depends on both the client and server being TypeScript within the same type system, so it isn't usable for clients written in other languages. GraphQL, being language-agnostic, would be the appropriate choice for that scenario.

Does tRPC require a schema like GraphQL?

No — this is tRPC's key differentiator. There's no separate schema language; you just write TypeScript functions on the server, and the client automatically infers their types directly, with no schema definition or code generation step required.

Is tRPC faster to set up than GraphQL?

Generally yes, for its target use case — tRPC has meaningfully less setup ceremony than GraphQL, since there's no schema to design, no resolvers to write in a separate pattern, and no code generation step to configure.

Can I build a public API with tRPC?

Not really — tRPC isn't designed for public or third-party consumption, since it lacks GraphQL's formal, documented schema that serves as a stable API contract for external consumers. GraphQL or REST are more appropriate choices for public-facing APIs.

Is GraphQL overkill for a small TypeScript project?

Often, yes — if your project is a single-team, full-stack TypeScript application (like a typical Next.js app), tRPC's simpler, zero-code-generation approach usually provides a better developer experience without needing GraphQL's cross-language flexibility, which goes unused in that scenario.

Get the next comparison by email

One email a week: new and trending developer tools, fresh comparisons, and what shipped. Unsubscribe in one click.