← Back to blog
··12 min read

tRPC vs oRPC vs ts-rest 2026: Choosing an End-to-End Type-Safe API Layer

tRPCoRPCts-restTypeScriptAPIType SafetyOpenAPI
tRPC vs oRPC vs ts-rest 2026: Choosing an End-to-End Type-Safe API Layer

If you build full-stack TypeScript apps, you have felt the specific pain these libraries exist to remove: the drift between what your server returns and what your client thinks it returns. REST with hand-written types rots the moment someone changes a response shape. OpenAPI code generation helps but adds a build step and a layer of generated noise. The end-to-end type-safe API libraries take a different route — you define a procedure once, and the client is fully typed from the same source, with no generation step and nothing to keep in sync.

tRPC is the library that made this pattern mainstream, and in 2026 it is still the incumbent: the largest ecosystem, the deepest TanStack Query integration, and the default for internal TypeScript apps. oRPC is the newer contender that keeps tRPC-style ergonomics but adds the things tRPC leaves to add-ons — first-class OpenAPI, Standard Schema support, native files and streaming. ts-rest takes the contract-first, REST-native path for teams who want typed HTTP rather than RPC. They look similar on a landing page and differ in ways that decide whether your API ages well. This guide makes the choice clear.

End-to-end type-safe API layers for TypeScript — tRPC, oRPC and ts-rest

End-to-end type-safe API layers for TypeScript — tRPC, oRPC and ts-rest

This is the library-level comparison. If you are still deciding between the broader API *styles* — REST versus GraphQL versus the RPC approach itself — start with our guide to REST vs GraphQL vs tRPC. This article assumes you have chosen the type-safe RPC direction and are picking the tool.

The Three at a Glance

LibraryWhat it isCore ideaBest for
tRPCThe original end-to-end type-safe RPC libraryDefine procedures, call them fully typed; no codegenInternal TS apps, monorepos, Next.js/React where you own the client
oRPCA newer RPC library with a real REST/OpenAPI surfacetRPC ergonomics + OpenAPI 3.1, Standard Schema, files, streamingPublic or mixed-client APIs that need an OpenAPI contract
ts-restA contract-first, REST-shaped type-safe layerDescribe REST endpoints in a shared contract; type both endsTeams shipping REST that want it typed, non-TS consumers

The mental model that keeps them straight: tRPC is RPC for your own app, oRPC is RPC plus a real REST surface, and ts-rest is typed REST. Everything below follows from that.

tRPC: The Incumbent

tRPC is the library that proved you do not need code generation to get a typed API. You write procedures on the server, grouped into routers; you export the router's *type* (not its code) to the client; and the client calls your procedures with full autocompletion and type checking. Nothing is generated, nothing is serialized into a schema file — the types flow through TypeScript's own inference.

ts
// server: a tRPC router. The input is validated with Zod,
// and the return type is inferred automatically.
import { initTRPC } from "@trpc/server";
import { z } from "zod";

const t = initTRPC.create();

export const appRouter = t.router({
  getUser: t.procedure
    .input(z.object({ id: z.string() }))
    .query(({ input }) => {
      return { id: input.id, name: "Ada" };
    }),
});

export type AppRouter = typeof appRouter;
ts
// client: fully typed from the exported AppRouter type.
// No codegen, no manually maintained response types.
const user = await trpc.getUser.query({ id: "123" });
//    ^? { id: string; name: string }

Two things keep tRPC the default in 2026. The first is the ecosystem: it has by far the largest adoption of the three — on the order of three million weekly npm downloads for the server package — which means the most boilerplates, the most Stack Overflow answers, the most middleware, and the most developers who already know it. The second is its TanStack Query integration, which is the deepest of any option here: tRPC procedures become React Query hooks with caching, request de-duplication, optimistic updates and invalidation essentially for free. For a React app, that pairing is a genuine productivity multiplier.

tRPC v11 went stable in March 2025 after a long pre-release, and it is a mature, actively maintained line — well into the 11.1x releases by late 2026, with no v12 yet. v11 also broadened schema support beyond Zod and lifted old type-depth limits that used to bite very large routers.

The trade-off: tRPC assumes you own both ends. It is RPC, not REST, so there are no stable URLs or HTTP verbs that an outside consumer can rely on, and OpenAPI output is an add-on — a separate community package rather than a core feature — that lags the core and forces your procedures into REST shapes. If your API will only ever be called by your own TypeScript client, none of that matters. If it will be consumed by a mobile team, a third party, or a non-TypeScript service, it matters a lot.

oRPC: tRPC Ergonomics With a Real REST Surface

oRPC starts from the same premise as tRPC — define a procedure, get a typed client, no codegen — and then systematically adds the things tRPC relegates to add-ons. It reached a stable 1.0 in late 2025 and has shipped actively since, so it is a real production option rather than an experiment.

The headline feature is OpenAPI. oRPC generates an OpenAPI 3.1 specification directly from your procedures as a core capability, not a bolt-on. That single fact changes what the API can be: the same definitions that give your TypeScript client its types also produce an accurate, always-current contract that Swagger UI, external developers and non-TypeScript clients can consume. You get RPC ergonomics internally and a real documented REST surface externally from one source.

ts
// oRPC: define a procedure once. The TypeScript client is typed,
// and the same definition feeds an OpenAPI 3.1 document.
import { os } from "@orpc/server";
import { z } from "zod";

export const getUser = os
  .input(z.object({ id: z.string() }))
  .output(z.object({ id: z.string(), name: z.string() }))
  .handler(async ({ input }) => {
    return { id: input.id, name: "Ada" };
  });

Beyond OpenAPI, oRPC leans into interoperability. It supports the Standard Schema spec, so you can validate with Zod, Valibot or ArkType interchangeably rather than being tied to one library — useful if you care about bundle size and have already chosen Valibot, for example (see our Zod vs Yup vs Valibot comparison for why that choice matters). It handles file uploads, Blobs and streaming natively, which tRPC and ts-rest treat as rough edges. And its server actions are framework-agnostic, so you are not locked into one framework's implementation of the pattern.

The trade-off: oRPC's ecosystem is a fraction of tRPC's — fewer downloads, fewer ready-made boilerplates, fewer battle-tested examples in the wild — and it has had far less time in production. The library also publishes its own benchmarks claiming faster type-checking and lower memory than tRPC on very large projects; those may well be true, but they are vendor-authored, so verify them against your own codebase rather than taking them as settled. If you need its features, the trade is usually worth it; if you do not, tRPC's maturity is hard to argue with.

ts-rest: Contract-First, REST-Native Type Safety

ts-rest rejects the RPC framing entirely. Instead of defining procedures, you define a contract — a plain description of REST endpoints, their methods, paths, inputs and response shapes — and both the server and the client are typed against that single contract. The result is ordinary REST (real URLs, real HTTP verbs, real status codes) that happens to be fully type-safe end to end.

ts
// ts-rest: a contract describes real REST endpoints.
// Server and client are both typed against it.
import { initContract } from "@ts-rest/core";
import { z } from "zod";

const c = initContract();

export const contract = c.router({
  getUser: {
    method: "GET",
    path: "/users/:id",
    responses: {
      200: z.object({ id: z.string(), name: z.string() }),
    },
  },
});

That contract-first, REST-shaped design is ts-rest's reason to exist. Because the API is REST underneath, it interoperates cleanly with non-TypeScript consumers, generating an OpenAPI document is natural, and you keep the familiar HTTP semantics that infrastructure, caching layers and other teams already understand. For a team that is going to ship REST regardless and simply wants to delete the class of bugs where the client and server disagree about a payload, ts-rest is the most direct fit.

The trade-off: ts-rest's development has visibly slowed — releases are less frequent than tRPC's or oRPC's — and its feature set is narrower: TanStack Query support is partial rather than deep, and it has no native file or streaming story. It is also the smallest community of the three. It remains a solid, focused tool for typed REST, but it is the most conservative choice and the one to double-check for active maintenance before you commit a long-lived product to it.

Developer Experience, OpenAPI and Ecosystem

A few dimensions decide most real choices:

  • Type-safe client with no codegen — all three deliver this; it is the whole category. The difference is what surrounds it.
  • TanStack Query integration — tRPC is deepest, oRPC is strong and improving, ts-rest is partial. For a React app that lives on React Query, this alone often points to tRPC or oRPC.
  • OpenAPI / REST surface — oRPC (core) and ts-rest (native REST) win; tRPC needs an add-on. If outside consumers or documentation tooling matter, this is decisive.
  • Schema flexibility — oRPC's Standard Schema support (Zod, Valibot, ArkType) is the most flexible; tRPC v11 broadened beyond Zod; ts-rest is Zod-oriented.
  • Files and streaming — oRPC handles these natively; the others treat them as edges.
  • Ecosystem and maturity — tRPC is far ahead (largest adoption, most boilerplates, most hireable), oRPC is newer but active and stable at 1.0, ts-rest is smaller and slowing.
  • Download figures quoted across comparison sites put tRPC's server package in the millions per week and oRPC and ts-rest in the few-hundred-thousand range — directionally useful for gauging ecosystem size, but worth checking on npm yourself since they move quickly.

    How to Choose

    Match the library to who calls your API, not to a feature checklist.

    Choose tRPC if you are building an internal, TypeScript-only product — a Next.js app, a monorepo, a React client you own — and you want the safest, most-supported default with the deepest TanStack Query integration. The moment you say "the client is our own code," tRPC is the path of least resistance.

    Choose oRPC if you want tRPC's ergonomics but also need a real OpenAPI 3.1 contract for third parties or non-TypeScript clients, want to validate with Valibot or ArkType rather than only Zod, or need native file and streaming support. It is the most feature-complete of the three and the right pick when your API has more than one kind of consumer.

    Choose ts-rest if you are committed to REST — real endpoints, real verbs, outside consumers — and you simply want that REST to be type-safe through a shared contract. Confirm it is still actively maintained for your timeline, then enjoy the most conservative, REST-native option.

    A quick heuristic: one TypeScript client points to tRPC, a public or mixed-client API with OpenAPI needs points to oRPC, and typed plain-REST points to ts-rest. And if your app is a single Next.js codebase with modest needs, remember that Server Actions may already cover you — reach for one of these libraries when you have a second client, a third party, or an API that must be documented.

    The Bottom Line

    Three end-to-end type-safe API libraries, three distinct bets about who consumes your API:

  • tRPC — the incumbent: the original no-codegen type-safe RPC library, with the largest ecosystem, the deepest TanStack Query integration, and the safest default for internal TypeScript apps. RPC for your own client.
  • oRPC — the feature-complete contender: tRPC-style ergonomics plus a core OpenAPI 3.1 surface, Standard Schema support, and native files and streaming, stable since 1.0 in late 2025. RPC plus a real REST contract.
  • ts-rest — the contract-first REST option: typed, REST-native endpoints from a shared contract, ideal for non-TypeScript consumers — but narrower in scope and slower to evolve. Typed REST.
  • There is no universal winner — there is the right fit for who calls your API and how much reach beyond TypeScript you need. Decide that first, and the library chooses itself.

    Starting a new API and want a proven foundation instead of a blank repo? Browse production-ready SaaS and backend starters on CodeCudos — every listing is quality-scored for TypeScript coverage, working flows and documentation — or, if you have built a polished tRPC or oRPC boilerplate, list it for sale. And if you are assembling the rest of the stack, our guides to the best tRPC templates and starters, Hono vs Express vs Fastify and TanStack Query vs SWR vs RTK Query cover what goes around the API layer.

    Frequently asked questions

    What is the difference between tRPC, oRPC, and ts-rest?▾

    All three give you end-to-end type safety between a TypeScript server and client — you define your procedures once and the client is fully typed with no code generation step and no manually maintained types — but they differ in how they expose the API and how far they reach beyond pure TypeScript. tRPC is the original and most widely adopted: it is RPC-first, pairs beautifully with TanStack Query, and assumes you own both ends of the connection, which makes it ideal for internal monorepo apps but means OpenAPI output is an add-on rather than a core feature. oRPC is a newer library that keeps tRPC-style ergonomics but builds OpenAPI 3.1 generation into its core, supports the Standard Schema spec so you can use Zod, Valibot or ArkType interchangeably, and handles files, Blobs and streaming natively, which makes it a strong fit when the API is public or consumed by non-TypeScript clients. ts-rest takes a different stance entirely: it is contract-first and REST-shaped, so you describe real HTTP endpoints in a shared contract and both server and client are typed against it, which suits teams that are shipping REST anyway and just want it typed. The quick rule: tRPC is RPC for your own app, oRPC is RPC plus a real REST/OpenAPI surface, and ts-rest is typed REST.

    Is oRPC a replacement for tRPC?▾

    oRPC is best understood as a feature-expanded alternative to tRPC rather than a drop-in replacement, and whether it should replace tRPC for you depends on what you need. If your project is a self-contained TypeScript app where the client and server live in the same repo and you are already happy with tRPC and its TanStack Query integration, there is little reason to switch — tRPC is stable, battle-tested and has by far the largest ecosystem and community. Where oRPC pulls ahead is the moment you need things tRPC does not do well out of the box: a real OpenAPI 3.1 specification for external consumers, native file and streaming support, Standard Schema so you are not tied to Zod, or framework-agnostic server actions. oRPC reached a stable 1.0 in late 2025 and has continued shipping actively since, so it is a credible production choice, but it has a smaller ecosystem and fewer years of battle-testing. Treat oRPC's own published benchmarks (it claims faster type-checking and lower memory on large projects) as vendor claims to verify yourself, not independent results.

    Which type-safe API library has the best OpenAPI support?▾

    oRPC has the strongest OpenAPI story of the three because it generates an OpenAPI 3.1 specification directly from your procedures as a core feature, which means third-party developers, non-TypeScript clients and documentation tools get an accurate, always-current contract without a separate build step. ts-rest also supports OpenAPI well: because it is contract-first and REST-shaped to begin with, generating an OpenAPI document from a ts-rest contract is natural and well supported. tRPC is the weakest here — it can produce OpenAPI output, but only through a separate community package (trpc-openapi / @trpc/openapi), and that path has historically lagged tRPC's core and requires you to shape your procedures to fit REST conventions. So if a machine-readable API contract for outside consumers is a hard requirement, oRPC or ts-rest are the natural fits and tRPC is a compromise.

    Do I still need any of these with Next.js Server Actions?▾

    Not always. If your app is a single Next.js codebase, your data needs are modest, and all mutations happen from your own React components, Server Actions already give you a typed function you can call from the client without building an API layer, and adding tRPC, oRPC or ts-rest on top can be unnecessary ceremony. These libraries start to earn their place when you outgrow that: when you have a separate client (a mobile app, a second frontend, a public API), when you want organised, reusable procedures with shared middleware for auth and logging, when you need fine-grained caching and request de-duplication from TanStack Query, or when you want an OpenAPI contract for outside consumers. A useful signal is a separate client or a third-party consumer — the moment your API has more than one caller, a dedicated type-safe layer pays for itself. oRPC is notable here because its server actions are framework-agnostic, so you are not locked to one framework's implementation.

    Can I use these libraries to build and sell a SaaS boilerplate?▾

    Yes, and a type-safe API layer is one of the features buyers specifically look for in a modern TypeScript SaaS boilerplate, because wiring tRPC or oRPC correctly — with auth middleware, input validation, error formatting, and TanStack Query on the client — is fiddly to get right and tedious to rebuild for every project. A starter that ships a clean, well-organised set of procedures, proper Zod (or Standard Schema) validation, protected and public procedure patterns, and a working client integration is doing real work for the buyer. Quality is what sells: buyers evaluate how idiomatic the setup is, whether the types genuinely flow end to end, how errors and auth are handled, and how well the README explains it. On a curated marketplace like CodeCudos, listings are quality-scored on exactly those signals, so a boilerplate with a thoughtful API layer stands out instead of getting lost among low-effort uploads.

    Related guides

    Browse Quality-Scored Code

    Every listing on CodeCudos is analyzed for code quality, security, and documentation. Find production-ready components, templates, and apps — or sell your own code and keep 90%.

    Browse Marketplace →