All posts
graphql-comparetrpc-comparecomparison

GraphQL vs tRPC: Which Should You Use?

An honest comparison of GraphQL and tRPC — key differences, when to pick each, and a clear recommendation.

SR

Suhail Roushan

August 6, 2026

·
4 min read
·
0 views

Every developer building a TypeScript API has faced this fork in the road: do you invest in a full GraphQL schema or keep things simple with tRPC's end-to-end type safety?

The real-world decision comes down to whether your API serves one TypeScript client or many different consumers. GraphQL vs tRPC isn't about which technology is better—it's about who's actually calling your backend and what they need from it.

GraphQL vs tRPC: The Key Differences

GraphQL is a query language with its own runtime, schema, and client ecosystem. tRPC is a thin RPC layer that exports TypeScript functions directly—no schema, no code generation, no separate client library.

The core difference is contract maintenance. GraphQL requires you to define and maintain a schema in SDL, then keep your resolvers in sync. tRPC infers types from your server code automatically, so the client and server can never drift apart.

Here's what that looks like in practice:

// GraphQL - you maintain schema and resolvers separately
// schema.graphql
type User {
  id: ID!
  name: String!
}

// resolver.ts
export const resolvers = {
  Query: {
    user: (_, { id }) => db.findUser(id)
  }
}

// tRPC - types flow directly from implementation
// server.ts
export const appRouter = router({
  getUser: procedure
    .input(z.string())
    .query(({ input }) => db.findUser(input))
});

// client.ts - getRouter returns fully typed result
const user = await trpc.getUser.query("123");

GraphQL gives you a contract that any language can consume. tRPC gives you zero-cost type safety but locks you into TypeScript on both ends.

When to Use GraphQL

Choose GraphQL when your API serves multiple clients: a React web app, an iOS app, an Android app, and third-party integrations. GraphQL's language-agnostic nature means a Python backend can serve a Kotlin client without friction.

GraphQL also wins when clients need flexible data shapes. A mobile app on a slow connection might request only id and name, while a dashboard fetches the full user with all nested relationships. That flexibility is GraphQL's killer feature.

Finally, GraphQL shines in microservice architectures where you need a gateway layer to aggregate data from multiple services. Tools like Apollo Federation exist specifically for this use case.

When to Use tRPC

Choose tRPC when you control both ends of the API and both are TypeScript. This is the default for most Next.js and Remix full-stack apps. You get types for free, zero runtime overhead, and no code generation step to break your build.

tRPC is also ideal for internal tools and admin dashboards where the API consumer is your own team. You'll never see a "TypeError: Cannot read properties of undefined" from a stale type definition again.

The real win is developer velocity. You can add a procedure, call it from the client, and have full type safety in under 60 seconds—no schema compilation, no introspection queries, no client regeneration.

GraphQL or tRPC: Which One Should You Pick?

The answer depends on one question: does your API have consumers outside your TypeScript ecosystem?

If yes—mobile apps, third-party partners, or non-TypeScript backends—use GraphQL. If no—it's just your own Next.js app talking to your own Node server—use tRPC.

GraphQL's schema is a contract. tRPC's types are a convenience. Public APIs need contracts. Internal ones need convenience.

My Take

I've built production APIs with both, and I'll be direct: tRPC is the better choice for 80% of new projects I see. Most teams building full-stack TypeScript apps don't need GraphQL's flexibility—they need speed and type safety, and tRPC delivers both with less complexity.

But if you're building a public API or have even one non-TypeScript consumer, skip tRPC entirely. You'll spend more time fighting its TypeScript-only constraint than you'd ever save on types.

The decision becomes obvious when you count your API consumers. One TypeScript client? tRPC. Anything else? GraphQL. That's the entire mental model.

Related posts

Written by Suhail Roushan — Full-stack developer. More posts on AI, Next.js, and building products at suhailroushan.com/blog.

Get in touch