SkillAgentSearch skills...

Orpc

Typesafe APIs Made Simple πŸͺ„

Install / Use

/learn @middleapi/Orpc

README

<div align="center"> <image align="center" src="https://orpc.dev/logo.webp" width=280 alt="oRPC logo" /> </div> <h1></h1> <div align="center"> <a href="https://codecov.io/gh/middleapi/orpc"> <img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/main/graph/badge.svg"> </a> <a href="https://www.npmjs.com/package/@orpc/client"> <img alt="weekly downloads" src="https://img.shields.io/npm/dw/%40orpc%2Fclient?logo=npm" /> </a> <a href="https://github.com/middleapi/orpc/blob/main/LICENSE"> <img alt="MIT License" src="https://img.shields.io/github/license/middleapi/orpc?logo=open-source-initiative" /> </a> <a href="https://discord.gg/TXEbwRBvQn"> <img alt="Discord" src="https://img.shields.io/discord/1308966753044398161?color=7389D8&label&logo=discord&logoColor=ffffff" /> </a> <a href="https://deepwiki.com/middleapi/orpc"> <img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"> </a> </div> <h3 align="center">Typesafe APIs Made Simple πŸͺ„</h3>

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:

    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
      }
    }
    
  2. Create your server:

    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')
    )
    
  3. Create your client:

    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<typeof router> = createORPCClient(link)
    
  4. Consume your API:

    import { orpc } from './client'
    
    const planets = await orpc.planet.list({ limit: 10 })
    
  5. Generate OpenAPI Spec:

    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

<table> <tr> <td align="center"><a href="https://screenshotone.com/?ref=orpc" target="_blank" rel="noopener" title="ScreenshotOne.com"><img src="https://avatars.githubusercontent.com/u/97035603?v=4" width="279" alt="ScreenshotOne.com"/><br />ScreenshotOne.com</a></td> </tr> </table>

πŸ₯‡ Gold Sponsor

<table> <tr> <td align="center"><a href="https://zuplo.link/orpc?ref=orpc" target="_blank" rel="noopener" title="Zuplo"><img src="https://avatars.githubusercontent.com/u/85497839?v=4" width="209" alt="Zuplo"/><br />Zuplo</a></td> </tr> </table>

πŸ₯ˆ Silver Sponsor

<table> <tr> <td align="center"><a href="https://misskey.io/?ref=orpc" target="_blank" rel="noopener" title="ζ‘δΈŠγ•γ‚“"><img src="https://avatars.githubusercontent.com/u/37681609?u=0dd4c7e4ba937cbb52b068c55914b1d8164dc0c7&amp;v=4" width="167" alt="ζ‘δΈŠγ•γ‚“"/><br />ζ‘δΈŠγ•γ‚“</a></td> <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="167" alt="christ12938"/><br />christ12938</a></td> </tr> </table>

Generous Sponsors

<table> <tr> <td align="center"><a href="https://github.com/ln-markets?ref=orpc" target="_blank" rel="noopener" title="LN Markets"><img src="https://avatars.githubusercontent.com/u/70597625?v=4" width="139" alt="LN Markets"/><br />LN Markets</a></td> </tr> </table>

Sponsors

<table> <tr> <td align="center"><a href="https://github.com/hrmcdonald?ref=orpc" target="_blank" rel="noopener" title="Reece McDonald"><img src="https://avatars.githubusercontent.com/u/39349270?v=4" width="119" alt="Reece McDonald"/><br />Reece McDonald</a></td> <td align="center"><a href="https://github.com/u1-liquid?ref=orpc" target="_blank" rel="noopener" title="あわわわとーにゅ"><img src="https://avatars.githubusercontent.com/u/17376330?u=de3353804be889f009f7e0a1582daf04d0ab292d&amp;v=4" width="119" alt="あわわわとーにゅ"/><br />あわわわとーにゅ</a></td> <td align="center"><a href="https://github.com/nicognaW?ref=orpc" target="_blank" rel="noopener" title="nk"><img src="https://avatars.githubusercontent.com/u/66731869?u=4699bda3a9092d3ec34fbd959450767bcc8b8b6d&amp;v=4" width="119" alt="nk"/><br />nk</a></td> <td align="center"><a href="https://github.com/supastarter?ref=orpc" target="_blank" rel="noopener" title="supastarter"><img src="https://avatars.githubusercontent.com/u/110960143?v=4" width="119" alt="supastarter"/><br />supasta
View on GitHub
GitHub Stars5.0k
CategoryDevelopment
Updated1h ago
Forks136

Languages

TypeScript

Security Score

100/100

Audited on Mar 25, 2026

No findings