Back to the blog
TypeScriptยท Jun 27, 2026ยท 8 min read

tRPC vs REST vs GraphQL in 2026: pick the right API layer for your team

tRPC v11 adds React Server Component support. GraphQL Federation v2 matured. REST now has universal OpenAPI 3.1 tooling. The decision has never been more nuanced - or clearer.

#typescript#api#trpc#graphql

The API layer question has a reputation for being tribal, but in 2026 the right answer is actually clearer than the debates suggest - because the use cases have separated more cleanly than they used to. tRPC v11 added React Server Component support, GraphQL Federation v2 matured into a genuine contract layer for large teams, and REST with OpenAPI 3.1 is the universal language for anything external. Here's how we think about the choice.

tRPC: maximum type safety, minimum ceremony

tRPC is the right call for TypeScript full-stack apps where the frontend and backend share a codebase or monorepo. You define procedures on the server, and the TypeScript types flow to the client automatically - no codegen, no schema files, no API contract to keep in sync. A type error in a backend procedure propagates to every client call site in the same build. For small-to-medium teams building product features fast, this eliminates a whole category of integration bugs.

// Server - define the procedure
const appRouter = router({
  post: router({
    byId: publicProcedure
      .input(z.object({ id: z.string() }))
      .query(async ({ input }) => db.posts.findUnique({ where: { id: input.id } })),
  }),
});

// Client - fully typed, no codegen, error if procedure changes
const { data } = trpc.post.byId.useQuery({ id: postId });
// data is typed from the server return type automatically

REST: the universal contract

REST with OpenAPI 3.1 is the right choice when your API will be consumed by clients you don't control: third-party integrations, mobile apps built by a separate team, webhook receivers, OAuth callbacks, and public developer APIs. The OpenAPI spec is a contract that any language, any tool, and any team can read. The 2026 tooling for REST has also improved significantly - `@hey-api/openapi-ts` and Zod OpenAPI generators close most of the type-safety gap that pushed teams to tRPC in the first place.

GraphQL: the right answer for diverse clients at scale

GraphQL earns its complexity when you have multiple client types (web, iOS, Android, third-party) that each need different shapes of the same underlying data. The query language lets clients request exactly what they need, the schema is self-documenting, and GraphQL Federation v2 gives you a scalable way to split the schema across teams without breaking client contracts. Below roughly ten engineers building for a single client, GraphQL's overhead rarely pays for itself.

The hybrid pattern that's emerged

The pattern used by most teams we've talked to: tRPC for the core application API (authenticated user-facing operations, internal product features), REST for external concerns (webhooks, OAuth callbacks, public API endpoints). The two coexist cleanly in a single codebase - tRPC handles the internal type-safe surface, REST handles everything that needs to be consumed outside the TypeScript monorepo boundary.

Decision table

  • Team size < 5, TypeScript full-stack, single client: tRPC. Zero ceremony, maximum type safety, ships fastest.
  • Public API or third-party consumers: REST + OpenAPI 3.1. The spec is the contract; type safety comes from generated clients.
  • Multiple clients (web, mobile, third-party) with different data shape needs: GraphQL. The flexibility justifies the tooling investment at this scale.
  • Mixed requirements: tRPC for internal + REST for external. The two compose naturally and don't force you to pick one for everything.

Written by Appesto Engineering.