Skip to main content
Why tRPC instead of GraphQL — for most projects — Frizmo Tech
Back to blog
EngineeringApril 29, 20267 min read

Why tRPC instead of GraphQL — for most projects

GraphQL has become almost a standard for new applications, but for many cases it is overkill. tRPC delivers 90% of the benefits with 10% of the complexity. When each works, and why we choose tRPC by default at Frizmo Tech.

Over the past 5 years, GraphQL has established itself as the "modern" way to build APIs. Apollo, Relay, schema-first approaches — an entire ecosystem promising elegance and flexibility for every project. The reality for most SaaS and e-commerce products, however, is more modest: GraphQL adds complexity that rarely pays off.

In this article, I'll explain why on most new projects we use tRPC instead of GraphQL — and when GraphQL remains the right choice.

What GraphQL promises

  • A single endpoint that returns exactly what the client requests (no over-fetching)
  • Strongly typed schema shared between frontend and backend
  • Standardized frontend tooling (Apollo, urql, codegen)
  • Federation for microservice architectures

This sounds great on paper. In practice, for a single-team monolith project (which 90% of SaaS startups are), most of these benefits are not used or carry more cost than benefit.

What hurts with GraphQL

Codegen pipeline

Schema-first GraphQL means every API change requires regenerating types. This is an extra build step that must be maintained in CI, on every PR. With tRPC, types come directly from TypeScript inference — zero generation, zero CI complexity.

The N+1 problem

GraphQL makes it easy for the client to request nested data ("users { posts { comments { author } } }"). Without careful resolver implementation with DataLoader, these queries can hammer databases. The solution — DataLoader + batching layer — adds another complexity layer that junior developers often miss.

Authorization complexity

In a REST/tRPC context, authorization is at the endpoint level — clear and understandable. In GraphQL, authorization needs to be field-level and reason about nested resolvers. This is possible but requires libraries like GraphQL Shield and significantly more glue code.

What tRPC delivers

tRPC is a TypeScript-first library for building end-to-end type-safe APIs without code generation. You define functions on the server, call them directly on the client, and types come automatically.

  • End-to-end type safety without a codegen step
  • IDE autocomplete from backend procedures on the frontend
  • Refactoring is trivial — rename a procedure on the server, TypeScript shows all client call sites
  • No bundle bloat from a GraphQL client (Apollo is ~30KB gzip)
  • Standard HTTP transport — easy CDN caching, REST inspection tools work
  • Validation via Zod — same schema for input + types

Real example

In Frizmo Platform we use tRPC for all server-client communications. We have about 80 procedures organized in routers. Time from "I have an idea for a new feature" to "PR merged" is usually under 2 hours for CRUD operations.

When we started the project, we considered GraphQL. We calculated the additional hours for codegen setup, DataLoader implementations, resolver-level auth, Apollo Client configuration — about 30-40 hours for initial setup and another 5-10 hours per month maintenance. With tRPC these hours go directly into new features.

When GraphQL remains the right choice

  • You have multiple front-end clients (web, iOS, Android, partners) with different data needs
  • The API is public, used by external developers
  • You have a microservice architecture with federation needs
  • You work in a team of 50+ where contract-first development is necessary
  • You have a complex data graph where clients genuinely need to query arbitrary nested structures

If none of these describe your project, GraphQL is likely over-engineering.

When neither tRPC nor GraphQL

For many projects, standard REST endpoints in Next.js API routes or server actions are enough. Especially for simple CRUD operations with little state. Not every project needs an RPC or query layer.

Conclusion

GraphQL is a powerful tool designed for specific complex scenarios. tRPC is a pragmatic solution for TypeScript-heavy products that do not need complex query needs.

The mistake I see most often is that teams pick GraphQL by default because it is fashionable. The result — weeks in build infrastructure instead of shipping features. For 90% of new projects, tRPC is the faster path to production without compromise in developer experience.

Have a question on a topic not covered?

Send an email with the topic and we'll cover it in a future article.

Get in touch