### Install Dependencies and Start Dev Server Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/playgrounds.md After cloning a playground, install its dependencies using npm and start the development server to run the application locally. ```bash # Install dependencies npm install # Start the development server npm run dev ``` -------------------------------- ### Install dependencies Source: https://github.com/dinwwwh/orpc/blob/main/CONTRIBUTING.md Run this command to install all necessary project dependencies. ```bash pnpm install ``` -------------------------------- ### Install Publisher Helper with bun Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/publisher.md Install the beta version of the publisher helper using bun. ```sh bun add @orpc/publisher@beta ``` -------------------------------- ### Install Publisher Helper with deno Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/publisher.md Install the beta version of the publisher helper using deno. ```sh deno add npm:@orpc/publisher@beta ``` -------------------------------- ### Server Setup for oRPC and tRPC Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/migrations/from-trpc.md This example shows the server setup for both oRPC and tRPC using Next.js. oRPC uses `RPCHandler` for its fetch adapter, while tRPC uses `fetchRequestHandler`. ```typescript import { RPCHandler } from '@orpc/server/fetch' const handler = new RPCHandler(appRouter, { interceptors: [ async ({ next, path }) => { try { return await next() } catch (error) { console.error(`❌ oRPC failed on ${path.join('.')}: `, error) throw error } } ] }) async function handleRequest(request: Request) { const { response } = await handler.handle(request, { prefix: '/api/orpc', context: await createORPCContext({ headers: request.headers }) }) return response ?? new Response('Not found', { status: 404 }) } export const GET = handleRequest export const POST = handleRequest ``` ```typescript import { fetchRequestHandler } from '@trpc/server/adapters/fetch' function handler(req: Request) { return fetchRequestHandler({ endpoint: '/api/trpc', req, router: appRouter, createContext: () => createTRPCContext({ headers: req.headers }), onError: ({ path, error }) => { console.error( `❌ tRPC failed on ${path ?? ''}: ${error.message}` ) } }) } export { handler as GET, handler as POST } ``` -------------------------------- ### Client Setup for oRPC and tRPC Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/migrations/from-trpc.md This example demonstrates setting up clients for both oRPC and tRPC. oRPC uses `createORPCClient` with a `RPCLink`, while tRPC uses `createTRPCProxyClient` with `httpLink`. ```typescript import { createORPCClient, onError } from '@orpc/client' import { RPCLink } from '@orpc/client/fetch' import { RouterClient } from '@orpc/server' const link = new RPCLink({ origin: 'http://localhost:3000', url: '/api/orpc', interceptors: [ onError((error) => { console.error(error) }) ], }) export const client: RouterClient = createORPCClient(link) // ---------------- Usage ---------------- const { planets } = await client.planet.list({ cursor: 0 }) ``` ```typescript import { createTRPCProxyClient, httpLink } from '@trpc/client' export const client = createTRPCProxyClient({ links: [ httpLink({ url: 'http://localhost:3000/api/trpc' }) ] }) // ---------------- Usage ---------------- const { planets } = await client.planet.list.query({ cursor: 0 }) ``` -------------------------------- ### Install Publisher Helper with yarn Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/publisher.md Install the beta version of the publisher helper using yarn. ```sh yarn add @orpc/publisher@beta ``` -------------------------------- ### Install Publisher Helper with npm Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/publisher.md Install the beta version of the publisher helper using npm. ```sh npm install @orpc/publisher@beta ``` -------------------------------- ### Install Publisher Helper with pnpm Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/publisher.md Install the beta version of the publisher helper using pnpm. ```sh pnpm add @orpc/publisher@beta ``` -------------------------------- ### Start Development Server Source: https://github.com/dinwwwh/orpc/blob/main/playgrounds/cloudflare/README.md Run this command to start the local development server for the oRPC playground. ```bash npm run dev ``` -------------------------------- ### Install @orpc/ratelimit Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/ratelimit.md Install the rate limiting package using your preferred package manager. ```sh npm install @orpc/ratelimit@beta ``` ```sh yarn add @orpc/ratelimit@beta ``` ```sh pnpm add @orpc/ratelimit@beta ``` ```sh bun add @orpc/ratelimit@beta ``` ```sh deno add npm:@orpc/ratelimit@beta ``` -------------------------------- ### Install @orpc/next Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/next.md Install the oRPC Next.js integration package using your preferred package manager. ```sh npm install @orpc/next@beta ``` ```sh yarn add @orpc/next@beta ``` ```sh pnpm add @orpc/next@beta ``` ```sh bun add @orpc/next@beta ``` ```sh deno add npm:@orpc/next@beta ``` -------------------------------- ### Manually Define Example Metadata Plugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/metadata.md Define a metadata plugin directly using `MetaPlugin` for full control over procedure types. This example shows how to add input and output examples to metadata. ```typescript import { os } from '@orpc/server' import z from 'zod' // ---cut--- import type { AnySchema, ErrorMap, InferSchemaInput, InferSchemaOutput, Meta, MetaPlugin, } from '@orpc/server' interface ExampleMeta< TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap > { inputExamples?: InferSchemaInput[] outputExamples?: InferSchemaOutput[] } interface ExampleMetaPlugin< TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap > extends MetaPlugin { name: 'example' } function exampleMeta< TInputSchema extends AnySchema, TOutputSchema extends AnySchema, TErrorMap extends ErrorMap, >( incoming: ExampleMeta ): ExampleMetaPlugin { return { name: 'example', apply(meta) { const current = meta.example as ExampleMeta | undefined return { ...meta, example: { ...current, ...incoming, } } }, } } function getExampleMeta( procedureOrLazy: { '~orpc': { meta: Meta } } ): ExampleMeta | undefined { return procedureOrLazy['~orpc'].meta.example as ExampleMeta | undefined } const procedure = os .input(z.object({ name: z.string() })) .output(z.object({ id: z.string(), name: z.string() })) .meta(exampleMeta({ inputExamples: [{ name: 'Alice' }], // <- typesafe outputExamples: [{ id: '1', name: 'Alice' }], // <- typesafe })) .handler(async ({ input }) => { return { id: '1', name: 'Alice' } }) ``` -------------------------------- ### Install @orpc/tanstack-query Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/tanstack-query.md Install the TanStack Query integration package using your preferred package manager. ```sh npm install @orpc/tanstack-query@beta ``` ```sh yarn add @orpc/tanstack-query@beta ``` ```sh pnpm add @orpc/tanstack-query@beta ``` ```sh bun add @orpc/tanstack-query@beta ``` ```sh deno add npm:@orpc/tanstack-query@beta ``` -------------------------------- ### Install ORPC Client with Bun Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Install the ORPC client package using Bun. This command adds the beta version of the client to your project. ```sh bun add @orpc/client@beta ``` -------------------------------- ### Install @orpc/json-schema via bun Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/smart-coercion.md Install the ORPC JSON Schema package using bun. ```sh bun add @orpc/json-schema@beta ``` -------------------------------- ### Install @orpc/json-schema via deno Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/smart-coercion.md Install the ORPC JSON Schema package using deno. ```sh deno add npm:@orpc/json-schema@beta ``` -------------------------------- ### Run development playground Source: https://github.com/dinwwwh/orpc/blob/main/CONTRIBUTING.md Navigate to the playground directory and start the development server to verify changes. ```bash cd playgrounds/next pnpm dev ``` -------------------------------- ### Install ORPC Client with Deno Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Install the ORPC client package using Deno. This command adds the beta version of the client to your project. ```sh deno add npm:@orpc/client@beta ``` -------------------------------- ### Basic Routing Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/routing.md Demonstrates how procedures are exposed by default (POST) and how to override this with custom methods and paths. ```APIDOC ## Basic Routing If you do not set OpenAPI routing metadata, a procedure is exposed as a `POST` endpoint whose path is derived from the router structure. ```ts import { os } from '@orpc/server' import { openapi } from '@orpc/openapi' const router = { planet: { list: os .meta(openapi({ method: 'GET', path: '/planets' })) .handler(async () => [{ id: 'earth', name: 'Earth' }]), create: os .handler(async () => ({})), } } ``` In this example, `list` is exposed as `GET /planets` because it overrides the default method and path. `create` keeps the default behavior, so it is exposed as `POST /planet/create`. ``` -------------------------------- ### Prefixes Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/routing.md Illustrates how to use the `prefix` option to prepend a path to procedures or entire routers. ```APIDOC ## Prefixes Define `prefix` to prepend a path to a procedure, or an entire router: ```ts const planetBuilder = os.meta(openapi({ prefix: '/planets' })) const listPlanets = planetBuilder .meta(openapi({ method: 'GET', path: '/' })) .handler(async () => [{ id: 'earth', name: 'Earth' }]) const createPlanet = planetBuilder .handler(async () => ({})) const router = os.meta(openapi({ prefix: '/api/v2' })).router({ planet: { list: listPlanets, create: createPlanet, }, }) ``` In this example, `listPlanets` is exposed as `GET /api/v2/planets/`. `createPlanet` is exposed as `POST /api/v2/planets/planet/create`. ``` -------------------------------- ### Setup OpenAPI Generator and Reference Plugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/openapi-reference.md Initializes the OpenAPI Generator and configures the OpenAPI Reference Plugin with a custom OpenAPI specification. This snippet demonstrates the basic setup for generating and serving API documentation. ```typescript import { OpenAPIGenerator } from '@orpc/openapi' import { OpenAPIReferencePlugin } from '@orpc/openapi/plugins' const generator = new OpenAPIGenerator({ converters: [ new ZodToJsonSchemaConverter(), ], }) const handler = new OpenAPIHandler(router, { plugins: [ new OpenAPIReferencePlugin({ spec: () => generator.generateSpec(router, { info: { title: 'ORPC Playground', version: '1.0.0', }, servers: [ { url: 'https://api.example.com/v1', }, ], }), }), ] }) ``` -------------------------------- ### Install ORPC Client with npm Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Install the ORPC client package using npm. This command adds the beta version of the client to your project. ```sh npm install @orpc/client@beta ``` -------------------------------- ### Complex Example with Nested Arrays and Files Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/bracket-notation.md Shows a comprehensive example of bracket notation handling nested objects, arrays with explicit indexes, and file uploads. ```bash curl -X POST http://example.com/api/example \ -F 'data[names][0][first]=John1' \ -F 'data[names][0][last]=Doe1' \ -F 'data[names][1][first]=John2' \ -F 'data[names][1][last]=Doe2' \ -F 'data[ages][0]=18' \ -F 'data[ages][2]=25' \ -F 'data[files][]=@/path/to/file1' \ -F 'data[files][]=@/path/to/file2' ``` ```json { "data": { "names": [ { "first": "John1", "last": "Doe1" }, { "first": "John2", "last": "Doe2" } ], "ages": ["18", "", "25"], "files": ["", ""] } } ``` -------------------------------- ### Install Swagger UI Type Definitions Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/openapi-reference.md Installs the necessary type definitions for Swagger UI. This is required for type safety when using Swagger UI. ```sh npm install swagger-ui @types/swagger-ui ``` -------------------------------- ### Install ORPC Client with Yarn Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Install the ORPC client package using Yarn. This command adds the beta version of the client to your project. ```sh yarn add @orpc/client@beta ``` -------------------------------- ### Install Evlog Packages Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/evlog.md Install the necessary Evlog and oRPC Evlog packages using your preferred package manager. ```sh npm install @orpc/evlog@beta evlog@beta ``` ```sh yarn add @orpc/evlog@beta evlog@beta ``` ```sh pnpm add @orpc/evlog@beta evlog@beta ``` ```sh bun add @orpc/evlog@beta evlog@beta ``` ```sh deno add npm:@orpc/evlog@beta npm:evlog@beta ``` -------------------------------- ### Install ORPC Client with pnpm Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Install the ORPC client package using pnpm. This command adds the beta version of the client to your project. ```sh pnpm add @orpc/client@beta ``` -------------------------------- ### Install @orpc/json-schema via yarn Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/smart-coercion.md Install the ORPC JSON Schema package using yarn. ```sh yarn add @orpc/json-schema@beta ``` -------------------------------- ### Shorthands Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/routing.md Demonstrates the use of shorthand helpers for common OpenAPI metadata configurations. ```APIDOC ## Shorthands For common cases, use the shorthand helpers: ```ts const listPlanets = os .meta(openapi.prefix('/planets')) .meta(openapi.method('GET')) .meta(openapi.path('/')) ``` ``` -------------------------------- ### Install @orpc/json-schema via pnpm Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/smart-coercion.md Install the ORPC JSON Schema package using pnpm. ```sh pnpm add @orpc/json-schema@beta ``` -------------------------------- ### Install and Use Published oRPC Client Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/advanced/publish-client-to-npm.md Install the published client package in your project and import the created API function to use it. ```bash pnpm add "" ``` ```typescript import { createMyApi } from '' const myApi = createMyApi('your-api-key') const output = await myApi.someMethod('input') ``` -------------------------------- ### Install @orpc/json-schema via npm Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/smart-coercion.md Install the ORPC JSON Schema package using npm. ```sh npm install @orpc/json-schema@beta ``` -------------------------------- ### Install Pino with oRPC Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/pino.md Install the necessary oRPC Pino integration package and Pino itself using your preferred package manager. ```sh npm install @orpc/pino@beta pino@beta ``` ```sh yarn add @orpc/pino@beta pino@beta ``` ```sh pnpm add @orpc/pino@beta pino@beta ``` ```sh bun add @orpc/pino@beta pino@beta ``` ```sh deno add npm:@orpc/pino@beta npm:pino@beta ``` -------------------------------- ### Start NestJS Development Server Source: https://github.com/dinwwwh/orpc/blob/main/playgrounds/nest/README.md Run this command to start the development server for the oRPC NestJS playground. Visit http://localhost:3000 to explore the OpenAPI client. ```bash npm run preview ``` -------------------------------- ### Implement Procedures and Middleware Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/learn-and-contribute/mini-orpc/procedure-builder.md Practical examples of defining authentication middleware, input-validated procedures, and protected procedures. ```typescript // Define reusable authentication middleware const authMiddleware = os .$context<{ user?: { id: string, name: string } }>() .middleware(async ({ context, next }) => { if (!context.user) { throw new Error('Unauthorized') } return next({ context: { user: context.user } }) }) // Public procedure with input validation 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 }) => { // Fetch planets with pagination return [{ id: 1, name: 'Earth' }] }) // Protected procedure with context and middleware export const createPlanet = os .$context<{ user?: { id: string, name: string } }>() .use(authMiddleware) .input(PlanetSchema.omit({ id: true })) .handler(async ({ input, context }) => { // Create new planet (user is guaranteed to exist via middleware) return { id: 2, name: input.name } }) export const router = { listPlanet, createPlanet, } ``` -------------------------------- ### Install OpenTelemetry Package Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/opentelemetry.md Install the OpenTelemetry integration package for oRPC using your preferred package manager. ```sh npm install @orpc/opentelemetry@beta ``` ```sh yarn add @orpc/opentelemetry@beta ``` ```sh pnpm add @orpc/opentelemetry@beta ``` ```sh bun add @orpc/opentelemetry@beta ``` ```sh deno add npm:@orpc/opentelemetry@beta ``` -------------------------------- ### Client-Side OpenTelemetry Setup Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/opentelemetry.md Configure the OpenTelemetry Web SDK with ORPCInstrumentation for client-side tracing. ```ts import { WebTracerProvider } from '@opentelemetry/sdk-trace-web' import { registerInstrumentations } from '@opentelemetry/instrumentation' import { ORPCInstrumentation } from '@orpc/opentelemetry' const provider = new WebTracerProvider() provider.register() registerInstrumentations({ instrumentations: [ new ORPCInstrumentation(), // [!code highlight] ], }) ``` -------------------------------- ### Fetch Adapter Interceptor Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/link.md Fetch adapter interceptors run just before the `fetch` call, providing access to the final URL and `RequestInit` options. This example demonstrates setting the `credentials` option for the fetch request. ```typescript const link = new RPCLink({ fetchInterceptors: [ async (options) => { const response = await options.next({ ...options, init: { ...options.init, credentials: 'include', }, }) return response }, ], }) ``` -------------------------------- ### Install Scalar Type Definitions Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/openapi-reference.md Installs the necessary type definitions for the Scalar API reference UI. This is required for type safety when using Scalar. ```sh npm install @scalar/api-reference ``` -------------------------------- ### URL Query Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/bracket-notation.md Demonstrates how nested object structures can be represented in a URL query string using bracket notation. ```bash curl 'http://example.com/api/example?name[first]=John&name[last]=Doe' ``` ```json { "name": { "first": "John", "last": "Doe" } } ``` -------------------------------- ### Server-Side OpenTelemetry Setup Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/opentelemetry.md Configure the OpenTelemetry Node.js SDK with ORPCInstrumentation for server-side tracing. ```ts import { NodeSDK } from '@opentelemetry/sdk-node' import { ORPCInstrumentation } from '@orpc/opentelemetry' const sdk = new NodeSDK({ instrumentations: [ new ORPCInstrumentation(), // [!code highlight] ], }) sdk.start() ``` -------------------------------- ### Define a GET Route with Middleware and Input Validation in oRPC Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/blog/v1-announcement.md This example demonstrates defining a GET route with multiple middleware functions, input validation using Zod, and defining type-safe errors. It shows how to make the route both Server Action compatible and callable as a regular function. ```typescript const getting = os .use(dbProvider) .use(requiredAuth) .use(rateLimit) .use(analytics) .use(sentryMonitoring) .use(retry({ times: 3 })) .route({ method: 'GET', path: '/getting/{id}' }) .input(z.object({ id: z.string() })) .use(canGetting, input => input.id) .errors({ SOME_TYPE_SAFE_ERROR: { data: z.object({ something: z.string() }) } }) .handler(async ({ input, errors, context }) => { // do something }) .actionable() // server action compatible .callable() // regular function compatible ``` -------------------------------- ### Setup RetryLinkPlugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/retry.md Import and initialize the RetryLinkPlugin for client-side request retries. Ensure you understand client context management. ```typescript import { RetryLinkPlugin, RetryLinkPluginContext } from '@orpc/client/plugins' interface ClientContext extends RetryLinkPluginContext {} const link = new RPCLink({ plugins: [ new RetryLinkPlugin(), ], }) ``` -------------------------------- ### Setup Body Limit Plugin with Max Body Size Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/body-limit.md Configure the RPCHandler with the BodyLimitHandlerPlugin, setting the maximum allowed request body size in bytes. This example sets the limit to 1MB. ```typescript const handler = new RPCHandler(router, { plugins: [ new BodyLimitHandlerPlugin({ maxBodySize: 1024 * 1024, // 1MB }), ], }) ``` -------------------------------- ### oRPC Client Usage Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/learn-and-contribute/mini-orpc/client-side-client.md Demonstrates how to set up an oRPC client and make a procedure call. Ensure you have an RPCLink instance configured with the correct URL. ```typescript const link = new RPCLink({ url: `${window.location.origin}/rpc`, }) export const orpc: RouterClient = createORPCClient(link) const result = await orpc.someProcedure({ input: 'example' }) ``` -------------------------------- ### Usage of Procedure and Router Clients Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/learn-and-contribute/mini-orpc/server-side-client.md Demonstrates how to instantiate and use clients for individual procedures and entire routers. ```typescript // Create a client for a single procedure const procedureClient = createProcedureClient(myProcedure, { context: { userId: '123' }, }) const result = await procedureClient({ input: 'example' }) // Create a client for an entire router const routerClient = createRouterClient(myRouter, { context: { userId: '123' }, }) const result = await routerClient.someProcedure({ input: 'example' }) ``` -------------------------------- ### Initialize RPCLink with Options Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/link.md Demonstrates how to initialize an RPCLink with various configuration options including origin, URL, headers, interceptors, plugins, and a custom fetch adapter. This setup is useful for configuring the communication channel to an RPC server. ```typescript const link = new RPCLink({ origin: 'https://example.com', url: '/rpc', headers: ({ context }) => ({ authorization: `Bearer ${token}`, }), interceptors: [ async ({ next, path }) => { console.time(path.join('.')) try { return await next() } catch (err) { console.error(`${path.join('.')}:`, err) throw err } finally { console.timeEnd(path.join('.')) } }, ], plugins: [ new RetryAfterLinkPlugin(), ], fetch: (request, init) => { // <- only available in fetch adapter return globalThis.fetch(request, { ...init, credentials: 'include', // Include cookies on cross-origin requests }) }, }) export const client = createORPCClient(link) ``` -------------------------------- ### Install @orpc/nest Package Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/nest.md Install the oRPC NestJS integration package using your preferred package manager. ```sh npm install @orpc/nest@beta ``` ```sh yarn add @orpc/nest@beta ``` ```sh pnpm add @orpc/nest@beta ``` ```sh bun add @orpc/nest@beta ``` ```sh deno add npm:@orpc/nest@beta ``` -------------------------------- ### Setting up Request Headers Handler Plugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/request-headers.md Shows how to initialize the `RPCHandler` and include the `RequestHeadersHandlerPlugin` in the plugins array. ```typescript import { RequestHeadersHandlerPlugin } from '@orpc/server/plugins' const handler = new RPCHandler(router, { plugins: [ new RequestHeadersHandlerPlugin(), ], }) ``` -------------------------------- ### Setup Input/Output Extensions with Effect Schema Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/effect.md Import the input-output extensions and define the base builder to use Effect Schema for .input and .output. ```typescript import '@orpc/experimental-effect/extensions/input-output' import { os } from '@orpc/server' export const base = os ``` -------------------------------- ### Setting up the Response Headers Handler Plugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/response-headers.md This snippet shows how to initialize the `RPCHandler` and include the `ResponseHeadersHandlerPlugin` in its configuration. ```typescript import { ResponseHeadersHandlerPlugin } from '@orpc/server/plugins' const handler = new RPCHandler(router, { plugins: [ new ResponseHeadersHandlerPlugin(), ], }) ``` -------------------------------- ### Install oRPC Packages Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/migrations/from-trpc.md Remove tRPC packages and install the equivalent oRPC packages using your preferred package manager. ```sh npm uninstall @trpc/server @trpc/client @trpc/tanstack-react-query npm install @orpc/server@beta @orpc/client@beta @orpc/tanstack-query@beta ``` ```sh yarn remove @trpc/server @trpc/client @trpc/tanstack-react-query yarn add @orpc/server@beta @orpc/client@beta @orpc/tanstack-query@beta ``` ```sh pnpm remove @trpc/server @trpc/client @trpc/tanstack-react-query pnpm add @orpc/server@beta @orpc/client@beta @orpc/tanstack-query@beta ``` ```sh bun remove @trpc/server @trpc/client @trpc/tanstack-react-query bun add @orpc/server@beta @orpc/client@beta @orpc/tanstack-query@beta ``` ```sh deno remove npm:@trpc/server npm:@trpc/client npm:@trpc/tanstack-react-query deno add npm:@orpc/server@beta npm:@orpc/client@beta npm:@orpc/tanstack-query@beta ``` -------------------------------- ### Fetch API Integration with Server Runtimes Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/adapters/fetch-api.md Examples show how to integrate the Fetch API handler with different server runtimes. Choose the snippet that matches your deployment environment. ```typescript Bun.serve({ fetch, }) ``` ```typescript export default { fetch, } ``` ```typescript Deno.serve(fetch) ``` ```typescript import { handle } from 'hono/aws-lambda' export const handler = handle({ fetch }) ``` -------------------------------- ### Install oRPC Effect Integration Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/integrations/effect.md Install the oRPC Effect integration and Effect itself using your preferred package manager. Ensure you are using the beta versions for both packages. ```sh npm install @orpc/experimental-effect@beta effect@beta ``` ```sh yarn add @orpc/experimental-effect@beta effect@beta ``` ```sh pnpm add @orpc/experimental-effect@beta effect@beta ``` ```sh bun add @orpc/experimental-effect@beta effect@beta ``` ```sh deno add npm:@orpc/experimental-effect@beta npm:effect@beta ``` -------------------------------- ### Basic Dedupe Plugin Setup Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/dedupe.md Initialize the DedupeLinkPlugin with default settings to prevent redundant requests. This basic setup deduplicates requests based on a general condition. ```typescript import { DedupeLinkPlugin } from '@orpc/client/plugins' const link = new RPCLink({ plugins: [ new DedupeLinkPlugin({ groups: [ { condition: () => true, context: {}, // Context used for the rest of the request lifecycle }, ], }), ], }) ``` -------------------------------- ### WebSocket Server with Bun Adapter Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/adapters/websocket.md Set up a WebSocket server using Bun's built-in capabilities and oRPC's RPCHandler. Handles incoming requests, upgrades WebSocket connections, and processes messages. Provides initial context for each message. ```typescript import { RPCHandler } from '@orpc/server/websocket' import { onError } from '@orpc/server' const handler = new RPCHandler(router, { interceptors: [ onError((error) => { console.error(error) }), ], }) Bun.serve({ fetch(req, server) { if (server.upgrade(req)) { return } return new Response('Upgrade failed', { status: 500 }) }, websocket: { async message(ws, message) { await handler.message(ws, message, { /** * Provide initial context if needed. The context can be an async function * that receives the per-call request as its first argument, and is **not** * related to the initial WebSocket upgrade request. */ context: request => ({}), }) }, async close(ws) { await handler.close(ws) }, } }) ``` -------------------------------- ### Error Response Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/protocol.md An example of an RPC error response, indicated by a 4xx or 5xx HTTP status code. The body contains an ORPCError object with `json` and `meta` fields. ```http HTTP/1.1 500 Internal Server Error Content-Type: application/json { "json": { "defined": false, "inferable": false, "code": "INTERNAL_SERVER_ERROR", "message": "Internal server error", "data": { "id": "1234567890" } }, "meta": [["bigint", "data", "id"]] } ``` -------------------------------- ### Compact Input Mapping for GET Request Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/input-and-output-mapping.md Uses `compact` mode to merge path and query parameters for GET requests. Define expected parameters using Zod schema. ```typescript const searchPlanets = os .meta(openapi({ method: 'GET', path: '/planets/{id}' })) .input(z.object({ id: z.string(), q: z.string().optional(), })) .handler(async ({ input }) => { return { id: input.id, q: input.q } }) ``` -------------------------------- ### Bun Redis Publisher Setup Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/helpers/publisher.md Configure a Bun Redis Publisher for event distribution. Ensure a separate Redis connection for subscriptions to avoid command conflicts. Customize key prefixes, serializers, and event replay settings. ```typescript import { BunRedisPublisher } from '@orpc/bun' import { redis } from 'bun' const publisher = new BunRedisPublisher(redis, { /** * Redis subscriber instance. * Pub/Sub takes over the connection, so a client with subscriptions * cannot execute commands and must use a dedicated connection. * * @default redis.duplicate() (lazily created on first listen) */ subscriber: redis.duplicate(), /** * The prefix to use for Redis keys. * * @default '' */ prefix: '', /** * Serializer for serialize and deserialize payloads. * * @default RPCSerializer */ serializer: undefined, replay: { /** * Whether event replay support is enabled. * * When enabled, published events are temporarily stored so new * subscribers can resume from a previous position using `lastEventId`. * * @default false */ enabled: false, /** * How long (in seconds) to retain events for replay. * * Expired events are cleaned up lazily for performance reasons, so * some events may remain available slightly longer than this period. * * @default 300 (5 min) */ seconds: 300 } }) ``` -------------------------------- ### Success Response Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/protocol.md An example of a successful RPC response, indicated by a 2xx HTTP status code. The body contains `json` and `meta` fields, where `meta` describes the serialization of types in `json`. ```http HTTP/1.1 200 OK Content-Type: application/json { "json": { "id": "1", "name": "Earth", "detached_at": "2022-01-01T00:00:00.000Z" }, "meta": [["bigint", "id"], ["date", "detached_at"]] } ``` -------------------------------- ### Setup Batching on Client Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/batch.md Initialize the client link with `BatchLinkPlugin` to group outgoing requests into batches. Define groups using conditions and associated contexts. ```typescript import { BatchLinkPlugin } from '@orpc/client/plugins' const link = new RPCLink({ url: '/rpc', plugins: [ new BatchLinkPlugin({ groups: [ { condition: () => true, context: {}, }, ], }), ], }) ``` -------------------------------- ### Transport Interceptor Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/link.md Transport interceptors run after input encoding and before response decoding. They are useful for inspecting or rewriting the request before it's sent over the network. This example adds a unique request ID header. ```typescript const link = new RPCLink({ transportInterceptors: [ async (options) => { const response = await options.next({ ...options, request: { ...options.request, headers: { ...options.request.headers, 'x-request-id': crypto.randomUUID(), }, }, }) return response }, ], }) ``` -------------------------------- ### Raw Server Output Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/advanced/expanding-type-support-for-openapi-link.md Illustrates the JSON-friendly format that the server returns for Date and bigint types, which the client needs to convert back to native types. ```typescript const rawOutput = { date: '2025-09-01T07:24:39.000Z', bigint: '123', } ``` -------------------------------- ### Create ORPC Client Instance Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Create an ORPC client instance using `createORPCClient` and a provided link. Supports both contract-first and normal approaches. ```ts import { createORPCClient } from '@orpc/client' import { RouterContractClient } from '@orpc/contract' import { RouterClient } from '@orpc/server' // if you are following contract-first approach const contractClient: RouterContractClient = createORPCClient(link) // if you are following normal approach const normalClient: RouterClient = createORPCClient(link) ``` -------------------------------- ### General RPC Interceptor Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/link.md Use general interceptors to observe or change any stage of an RPC request, including input encoding, transport, and response decoding. This example logs the request path and timing information. ```typescript const link = new RPCLink({ interceptors: [ async ({ next, path, input }) => { console.time(path.join('.')) try { const output = await next() return output } catch (err) { console.error(`${path.join('.')}:`, err) throw err } finally { console.timeEnd(path.join('.')) } }, ], }) ``` -------------------------------- ### Metadata Reset Example Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/routing.md Illustrates how metadata can be reset to its default behavior by setting it to `undefined`. ```APIDOC ::: info Metadata resets to its default behavior when set to `undefined` in subsequent calls: ```ts const example = os .meta(openapi({ prefix: '/api/v2' })) .meta(openapi({ prefix: undefined })) ``` In this example, the final `prefix` is `undefined`, so no prefix is applied to `example`. ::: ``` -------------------------------- ### Create Typesafe ORPC Clients Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/link.md Shows how to create typesafe clients using `createORPCClient` with an RPCLink. Supports both contract-first and normal development approaches. ```typescript import { createORPCClient } from '@orpc/client' import { RouterContractClient } from '@orpc/contract' import { RouterClient } from '@orpc/server' // if you are following contract-first approach const contractClient: RouterContractClient = createORPCClient(link) // if you are following normal approach const normalClient: RouterClient = createORPCClient(link) ``` -------------------------------- ### Setup Response Validation Plugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/response-validation.md Instantiate the ResponseValidationLinkPlugin with your contract to enable response validation. ```typescript import { ResponseValidationLinkPlugin } from '@orpc/contract/plugins' const link = new RPCLink({ plugins: [ new ResponseValidationLinkPlugin(contract), ], }) ``` -------------------------------- ### Setup Request Validation Plugin Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/request-validation.md Initialize the RequestValidationLinkPlugin with your contract to enable request validation. ```typescript import { RequestValidationLinkPlugin } from '@orpc/contract/plugins' const link = new RPCLink({ plugins: [ new RequestValidationLinkPlugin(contract), ], }) ``` -------------------------------- ### Serve OpenAPI Spec and Scalar UI with Node.js Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/openapi/scalar.md This example sets up an HTTP server to serve the OpenAPI specification at `/spec.json` and renders the Scalar interactive API reference UI at `/`. It handles API requests via `openAPIHandler` and generates the OpenAPI spec using `openAPIGenerator`. ```typescript import { createServer } from 'node:http' import { OpenAPIGenerator } from '@orpc/openapi' import { OpenAPIHandler } from '@orpc/openapi/node' import { CORSPlugin } from '@orpc/server/plugins' import { ZodToJsonSchemaConverter } from '@orpc/zod' const openAPIHandler = new OpenAPIHandler(router, { plugins: [ new CORSHandlerPlugin(), ], }) const openAPIGenerator = new OpenAPIGenerator({ schemaConverters: [ new ZodToJsonSchemaConverter(), ], }) const server = createServer(async (req, res) => { const { matched } = await openAPIHandler.handle(req, res, { prefix: '/api', }) if (matched) { return } if (req.url === '/spec.json') { const spec = await openAPIGenerator.generate(router, { info: { title: 'My Playground', version: '1.0.0', }, servers: [ { url: '/api' }, /** Use an absolute URL in production. */ ], security: [{ bearerAuth: [] }], components: { securitySchemes: { bearerAuth: { type: 'http', scheme: 'bearer', }, }, }, }) res.writeHead(200, { 'Content-Type': 'application/json' }) res.end(JSON.stringify(spec)) return } const html = ` My Client
` res.writeHead(200, { 'Content-Type': 'text/html' }) res.end(html) }) server.listen(3000, () => { console.log('Playground is available at http://localhost:3000') }) ``` -------------------------------- ### Configure Server-Side RPCHandler Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/adapters/message-port.md Sets up the RPCHandler on the server port, including error handling and context provision. The serverPort must be started after configuration. ```typescript import { RPCHandler } from '@orpc/server/message-port' import { onError } from '@orpc/server' const handler = new RPCHandler(router, { interceptors: [ onError((error) => { console.error(error) }), ], }) handler.upgrade(serverPort, { /** * Provide initial context if needed. The context can be an async function * that receives the per-call request as its first argument, and is **not** * related to the initial upgrade request. */ context: request => ({}), }) serverPort.start() ``` -------------------------------- ### Initialize RPCHandler with Interceptors and Plugins Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/rpc/handler.md Demonstrates the initialization of an RPCHandler with custom logging interceptors and CORS plugins. This setup is useful for general request handling and cross-origin resource sharing. ```typescript const handler = new RPCHandler(router, { interceptors: [ async ({ next, path }) => { console.time(path.join('.')) try { return await next() } catch (err) { console.error(`${path.join('.')}:`, err) throw err } finally { console.timeEnd(path.join('.')) } } ], plugins: [ new CORSHandlerPlugin() ], }) ``` -------------------------------- ### Create ORPC Client with Context Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/client/client-side.md Demonstrates creating an ORPC client with a defined ClientContext interface. Use this to pass values like auth tokens or cache hints with each call. ```typescript interface ClientContext { token?: string } // if you are following contract-first approach const client: RouterContractClient = createORPCClient(link) // if you are following normal approach const client: RouterClient = createORPCClient(link) const output = await client.someProcedure(input, { context: { token: 'abc123', }, }) ``` -------------------------------- ### Setup CSRFGuardHandlerPlugin with OpenAPIHandler Source: https://github.com/dinwwwh/orpc/blob/main/apps/content/docs/plugins/csrf-guard.md Import and use CSRFGuardHandlerPlugin when initializing an OpenAPIHandler to enable CSRF protection. ```typescript import { OpenAPIHandler } from '@orpc/openapi/fetch' import { CSRFGuardHandlerPlugin } from '@orpc/server/plugins' const handler = new OpenAPIHandler(router, { plugins: [ new CSRFGuardHandlerPlugin(), ], }) ```