Integrations
Integrating oRPC with your existing stacks, environments, and frameworks.
Integrate oRPC with various stacks, environments, and frameworks effortlessly. oRPC is designed with the Fetch API in mind, making it compatible with any modern environment or framework.
It uses the highly performant Hono RegExpRouter under the hood, ensuring low-latency routing. Whether you're targeting serverless, edge environments, or traditional backends, oRPC is optimized for all scenarios.
Quick Example
import { ORPCHandler } from '@orpc/server/fetch'
import { OpenAPIServerlessHandler } from '@orpc/openapi/fetch'
import { router } from 'examples/server'
import { ZodCoercer } from '@orpc/zod'
const openapiHandler = new OpenAPIServerlessHandler(router, {
schemaCoercers: [
new ZodCoercer(),
],
})
const orpcHandler = new ORPCHandler(router)
export async function fetch(request: Request) {
const url = new URL(request.url)
if (url.pathname.startsWith('/api')) {
const { matched, response } = await openapiHandler.handle(request, {
prefix: '/api'
})
if (matched) {
return response
}
}
if (url.pathname.startsWith('/rpc')) {
const { matched, response } = await orpcHandler.handle(request, {
prefix: '/rpc'
})
if (matched) {
return response
}
}
return new Response('Not found', { status: 404 })
}
Node.js
import { createServer } from 'node:http'
import { ORPCHandler } from '@orpc/server/node'
import { OpenAPIServerlessHandler } from '@orpc/openapi/node'
import { router } from 'examples/server'
import { ZodCoercer } from '@orpc/zod'
const openapiHandler = new OpenAPIServerlessHandler(router, {
schemaCoercers: [
new ZodCoercer(),
],
})
const orpcHandler = new ORPCHandler(router)
const server = createServer(async (req, res) => {
if (req.url?.startsWith('/api')) {
const { matched } = await openapiHandler.handle(req, res, {
prefix: '/api',
context: {},
})
if (matched) {
return
}
}
if (req.url?.startsWith('/rpc')) {
const { matched } = await orpcHandler.handle(req, res, {
prefix: '/rpc',
context: {},
})
if (matched) {
return
}
}
res.statusCode = 404
res.end('Not found')
})
server.listen(3000, () => {
console.log('Server is available at http://localhost:3000')
})
Express.js
import express from 'express'
import { ORPCHandler } from '@orpc/server/node'
import { OpenAPIServerlessHandler } from '@orpc/openapi/node'
import { router } from 'examples/server'
import { ZodCoercer } from '@orpc/zod'
const app = express()
const openapiHandler = new OpenAPIServerlessHandler(router, {
schemaCoercers: [
new ZodCoercer(),
],
})
app.use('/api/*', async (req, res, next) => {
const { matched } = await openapiHandler.handle(req, res, {
prefix: '/api',
context: {},
})
if (matched) {
return
}
next()
})
const orpcHandler = new ORPCHandler(router)
app.use('/rpc/*', async (req, res, next) => {
const { matched } = await orpcHandler.handle(req, res, {
prefix: '/rpc',
context: {},
})
if (matched) {
return
}
next()
})
app.listen(3000, () => {
console.log('Server is available at http://localhost:3000')
})
Hono
import { Hono } from 'hono'
import { ORPCHandler, createMiddleware } from '@orpc/server/hono'
import { OpenAPIServerlessHandler } from '@orpc/openapi/hono'
import { router } from 'examples/server'
import { ZodCoercer } from '@orpc/zod'
const app = new Hono()
const openapiHandler = new OpenAPIServerlessHandler(router, {
schemaCoercers: [
new ZodCoercer(),
],
})
app.use('/api/*', createMiddleware(openapiHandler, {
prefix: '/api',
context: async (c) => {
return {}
}
}))
const orpcHandler = new ORPCHandler(router)
app.use('/rpc/*', createMiddleware(orpcHandler, {
prefix: '/rpc',
context: async (c) => {
return {}
}
}))
export default app
Next.js
import { OpenAPIServerlessHandler } from '@orpc/openapi/next'
import { serve } from '@orpc/server/next'
import { router } from 'examples/server'
import { ZodCoercer } from '@orpc/zod'
const openapiHandler = new OpenAPIServerlessHandler(router, {
schemaCoercers: [
new ZodCoercer(),
],
})
export const { GET, POST, PUT, PATCH, DELETE } = serve(openapiHandler, {
prefix: '/api',
context: async (req) => {
return {}
},
})
import { serve, ORPCHandler } from '@orpc/server/next'
import { router } from 'examples/server'
const orpcHandler = new ORPCHandler(router)
export const { GET, POST, PUT, PATCH, DELETE } = serve(orpcHandler, {
prefix: '/rpc',
context: async (req) => {
return {}
},
})
Cloudflare Workers
import { ORPCHandler } from '@orpc/server/fetch'
import { OpenAPIServerlessHandler } from '@orpc/openapi/fetch'
import { router } from 'examples/server'
import { ZodCoercer } from '@orpc/zod'
const openapiHandler = new OpenAPIServerlessHandler(router, {
schemaCoercers: [
new ZodCoercer(),
],
})
const orpcHandler = new ORPCHandler(router)
export default {
async fetch(request: Request) {
const url = new URL(request.url)
if (url.pathname.startsWith('/api')) {
const { matched, response } = await openapiHandler.handle(request, {
prefix: '/api'
})
if (matched) {
return response
}
}
if (url.pathname.startsWith('/rpc')) {
const { matched, response } = await orpcHandler.handle(request, {
prefix: '/rpc'
})
if (matched) {
return response
}
}
return new Response('Not found', { status: 404 })
},
}
Other Environments and Frameworks
oRPC works in any modern environment that supports the creating server with Fetch API.