Skip to main content
@orpc/server is the core server-side package for oRPC. It lets you define procedures, compose routers, attach middleware, and serve requests over HTTP or any other transport.

Installation

npm install @orpc/server

The os builder

Everything starts with the os export — a pre-configured Builder instance you use to define procedures, middleware, and routers.
import { os } from '@orpc/server'

// Define a simple procedure
const hello = os
  .input(/* zod / valibot / arktype schema */)
  .output(/* schema */)
  .handler(async ({ input }) => {
    return { message: `Hello, ${input.name}!` }
  })
The builder is fully chainable. Every method call returns a new builder so your original os instance is never mutated. This means you can safely derive shared base builders:
// A base builder with shared context type
const base = os.$context<{ userId: string }>()

// A base builder with shared error definitions
const authed = base.errors({
  UNAUTHORIZED: { status: 401, message: 'Not authenticated' },
})

Quick example

import { ORPCError, os } from '@orpc/server'
import * as z from 'zod'

const listPlanets = os
  .input(z.object({ limit: z.number().int().min(1).max(100).optional() }))
  .handler(async ({ input }) => {
    return [{ id: 1, name: 'Earth' }]
  })

const createPlanet = os
  .$context<{ headers: Record<string, string> }>()
  .use(({ context, next }) => {
    const user = parseJWT(context.headers.authorization?.split(' ')[1])
    if (user) return next({ context: { user } })
    throw new ORPCError('UNAUTHORIZED')
  })
  .input(z.object({ name: z.string() }))
  .handler(async ({ input, context }) => {
    return { id: 2, name: input.name }
  })

export const router = {
  planet: { list: listPlanets, create: createPlanet },
}

What’s in this section

Procedures

Define typed inputs, outputs, errors, and handlers.

Routers

Compose procedures into nested routers.

Middleware

Intercept and transform the pipeline with middleware.

Context

Pass request-scoped data through the call stack.

Errors

Typed, serializable errors with ORPCError.

Contract-First

Define the API shape before implementing it.

Adapters

Plug in to Node.js, Fetch, Fastify, AWS Lambda, and more.

Plugins

CORS, batching, CSRF protection, and response headers.

Server Actions

Use oRPC procedures as Next.js Server Actions.

Streaming & SSE

Stream responses with typed async iterators.

WebSockets

Real-time two-way communication over WebSockets.

OpenTelemetry

Distributed tracing with @orpc/otel.

NestJS

Deep integration with the NestJS framework.

Build docs developers (and LLMs) love