MCPcopy Index your code
hub / github.com/middleapi/orpc

github.com/middleapi/orpc @v1.14.6

repository ↗ · DeepWiki ↗ · release v1.14.6 ↗ · Ask this repo → · + Follow
2,629 symbols 7,960 edges 1,057 files 270 documented · 10% updated todayv2.0.0-beta.14 · 2026-07-03★ 5,36941 open issues
README

oRPC logo

codecov weekly downloads MIT License Discord Ask DeepWiki

Typesafe APIs Made Simple 🪄

oRPC is a powerful combination of RPC and OpenAPI, makes it easy to build APIs that are end-to-end type-safe and adhere to OpenAPI standards


Highlights

  • 🔗 End-to-End Type Safety: Ensure type-safe inputs, outputs, and errors from client to server.
  • 📘 First-Class OpenAPI: Built-in support that fully adheres to the OpenAPI standard.
  • 📝 Contract-First Development: Optionally define your API contract before implementation.
  • 🔍 First-Class OpenTelemetry: Seamlessly integrate with OpenTelemetry for observability.
  • ⚙️ Framework Integrations: Seamlessly integrate with TanStack Query (React, Vue, Solid, Svelte, Angular), SWR, Pinia Colada, and more.
  • 🚀 Server Actions: Fully compatible with React Server Actions on Next.js, TanStack Start, and other platforms.
  • 🔠 Standard Schema Support: Works out of the box with Zod, Valibot, ArkType, and other schema validators.
  • 🗃️ Native Types: Supports native types like Date, File, Blob, BigInt, URL, and more.
  • ⏱️ Lazy Router: Enhance cold start times with our lazy routing feature.
  • 📡 SSE & Streaming: Enjoy full type-safe support for SSE and streaming.
  • 🌍 Multi-Runtime Support: Fast and lightweight on Cloudflare, Deno, Bun, Node.js, and beyond.
  • 🔌 Extendability: Easily extend functionality with plugins, middleware, and interceptors.

Documentation

You can find the full documentation here.

Packages

Overview

This is a quick overview of how to use oRPC. For more details, please refer to the documentation.

  1. Define your router:

```ts import type { IncomingHttpHeaders } from 'node:http' import { ORPCError, os } from '@orpc/server' import * as z from 'zod'

const PlanetSchema = z.object({ id: z.number().int().min(1), name: z.string(), description: z.string().optional(), })

export const listPlanet = os .input( z.object({ limit: z.number().int().min(1).max(100).optional(), cursor: z.number().int().min(0).default(0), }), ) .handler(async ({ input }) => { // your list code here return [{ id: 1, name: 'name' }] })

export const findPlanet = os .input(PlanetSchema.pick({ id: true })) .handler(async ({ input }) => { // your find code here return { id: 1, name: 'name' } })

export const createPlanet = os .$context<{ headers: IncomingHttpHeaders }>() .use(({ context, next }) => { const user = parseJWT(context.headers.authorization?.split(' ')[1])

   if (user) {
     return next({ context: { user } })
   }

   throw new ORPCError('UNAUTHORIZED')
 })
 .input(PlanetSchema.omit({ id: true }))
 .handler(async ({ input, context }) => {
   // your create code here
   return { id: 1, name: 'name' }
 })

export const router = { planet: { list: listPlanet, find: findPlanet, create: createPlanet } } ```

  1. Create your server:

```ts import { createServer } from 'node:http' import { RPCHandler } from '@orpc/server/node' import { CORSPlugin } from '@orpc/server/plugins'

const handler = new RPCHandler(router, { plugins: [new CORSPlugin()] })

const server = createServer(async (req, res) => { const result = await handler.handle(req, res, { context: { headers: req.headers } })

 if (!result.matched) {
   res.statusCode = 404
   res.end('No procedure matched')
 }

})

server.listen( 3000, '127.0.0.1', () => console.log('Listening on 127.0.0.1:3000') ) ```

  1. Create your client:

```ts import type { RouterClient } from '@orpc/server' import { createORPCClient } from '@orpc/client' import { RPCLink } from '@orpc/client/fetch'

const link = new RPCLink({ url: 'http://127.0.0.1:3000', headers: { Authorization: 'Bearer token' }, })

export const orpc: RouterClient = createORPCClient(link) ```

  1. Consume your API:

```ts import { orpc } from './client'

const planets = await orpc.planet.list({ limit: 10 }) ```

  1. Generate OpenAPI Spec:

```ts import { OpenAPIGenerator } from '@orpc/openapi' import { ZodToJsonSchemaConverter } from '@orpc/zod/zod4'

const generator = new OpenAPIGenerator({ schemaConverters: [new ZodToJsonSchemaConverter()] })

const spec = await generator.generate(router, { info: { title: 'Planet API', version: '1.0.0' } })

console.log(spec) ```

Sponsors

If you find oRPC valuable and would like to support its development, you can do so here: GitHub Sponsors.

🏆 Platinum Sponsor

ScreenshotOne.com ScreenshotOne.com

🥈 Silver Sponsor

村上さん 村上さん

🥉 Bronze Sponsor

plancraft plancraft

Generous Sponsors

LN Markets LN Markets

Sponsors

Reece McDonald Reece McDonald nk nk supastarter supastarter Dexter Miguel Dexter Miguel herrfugbaum herrfugbaum Ryota Murakami Ryota Murakami David Cramer David Cramer
Valerii Petryniak Valerii Petryniak Valerii Strilets Valerii Strilets Kyle Mistele Kyle Mistele Andrew Peters Andrew Peters Ryan Vogel Ryan Vogel christ12938 christ12938 Peter Adam Peter Adam
Ryan Soderberg Ryan Soderberg shota shota

Backers

David Walsh David Walsh Adam Tkaczyk Adam Tkaczyk

Extension points exported contracts — how you extend this code

LinkFetchPlugin (Interface)
(no doc) [7 implementers]
packages/client/src/adapters/fetch/plugin.ts
SchemaConverter (Interface)
(no doc) [6 implementers]
packages/openapi/src/schema-converter.ts
FetchHandlerPlugin (Interface)
(no doc) [7 implementers]
packages/server/src/adapters/fetch/plugin.ts
Ratelimiter (Interface)
(no doc) [8 implementers]
packages/ratelimit/src/types.ts
R2Checksums (Interface)
(no doc) [5 implementers]
playgrounds/cloudflare-worker/worker-configuration.d.ts
ContractProcedureBuilderWithInputOutput (Interface)
(no doc) [3 implementers]
packages/contract/src/builder-variants.ts
ORPCGlobalContext (Interface)
* Extend oRPC global context to make it type-safe inside your handlers/middlewares
playgrounds/nest/src/app.module.ts
ToFetchResponseOptions (Interface)
(no doc)
packages/standard-server-fetch/src/response.ts

Core symbols most depended-on inside this repo

handler
called by 314
packages/server/src/builder.ts
get
called by 311
playgrounds/cloudflare-worker/worker-configuration.d.ts
queryOptions
called by 284
packages/solid-query/src/procedure-utils.ts
key
called by 279
packages/solid-query/src/general-utils.ts
next
called by 260
packages/shared/src/iterator.ts
route
called by 236
packages/contract/src/builder-variants.ts
push
called by 221
packages/shared/src/queue.ts
use
called by 202
packages/server/src/implementer.ts

Shape

Method 841
Interface 680
Function 678
Class 418
Enum 12

Languages

TypeScript100%

Modules by API surface

playgrounds/cloudflare-worker/worker-configuration.d.ts635 symbols
packages/server/src/builder-variants.ts47 symbols
packages/nest/src/implement.test.ts25 symbols
packages/contract/src/builder-variants.ts25 symbols
packages/tanstack-query/src/procedure-utils.ts24 symbols
packages/server/src/builder.ts22 symbols
packages/durable-iterator/src/durable-object/websocket.ts22 symbols
packages/standard-server-peer/src/codec.ts20 symbols
packages/standard-server-peer/src/server.ts19 symbols
packages/standard-server-peer/src/client.ts18 symbols
packages/json-schema/src/coercer.ts15 symbols
packages/durable-iterator/src/durable-object/resume-storage.ts15 symbols

Dependencies from manifests, versioned

@ai-sdk/google3.0.43 · 1×
@ai-sdk/react3.0.118 · 1×
@angular/core21.2.4 · 1×
@ark/schema0.56.0 · 1×
@astrojs/check0.9.7 · 1×
@astrojs/react4.4.2 · 1×
@cloudflare/vite-plugin1.28.0 · 1×
@cloudflare/vitest-pool-workers0.13.0 · 1×
@cloudflare/workers-types4.20260313.1 · 1×
@electron-toolkit/preload3.0.2 · 1×
@electron-toolkit/tsconfig2.0.0 · 1×

For agents

$ claude mcp add orpc \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact