oRPC
Type-safe RPC for TypeScript. Define procedures on the server and call them from the client with full end-to-end type inference.
Integration
oRPC is a type-safe RPC library for TypeScript. It lets you define server procedures and call them from both server components and client components with full type safety.
Install
terminalbash
npm install @orpc/server @orpc/clientDefine your router
router.tstypescript
import { os } from "@orpc/server";
export const router = {
time: {
getCurrent: os.handler(() => {
return Date.now();
})
}
};Create the client
client.tstypescript
import { createORPCClient } from '@orpc/client'
import { RPCLink } from '@orpc/client/fetch'
import type { RouterClient } from '@orpc/server'
import type { router } from './router'
const baseURL =
typeof window !== 'undefined'
? `${window.location.origin}/rpc`
: process.env.RPC_URL || 'http://localhost:3000/rpc'
const link = new RPCLink({ url: baseURL })
export const orpc: RouterClient<typeof router> =
createORPCClient(link)Register the RPC handler
server/rpc/[...rest].tstypescript
import { RPCHandler } from '@orpc/server/node'
import { onError } from '@orpc/server'
import { router } from '../../router'
const handler = new RPCHandler(router, {
interceptors: [
onError((error) => {
console.error(error)
})
]
})
async function handleRequest(req: any, res: any) {
const { matched } = await handler.handle(req, res, {
prefix: '/rpc',
context: {}
})
if (matched) return
res.json({ error: 404 })
}
export const HEAD = handleRequest
export const GET = handleRequest
export const POST = handleRequest
export const PUT = handleRequest
export const PATCH = handleRequest
export const DELETE = handleRequestCall procedures from a server page
app/pages/index.tsxtypescript
import { useHtml } from "nukejs"
import { orpc } from "../../client"
export default async function Index() {
useHtml({ title: "Home" })
const currentTime = await orpc.time.getCurrent()
return (
<main>
<h1>Server time</h1>
<p>{currentTime}</p>
</main>
)
}Call procedures from a client component
app/components/TimeDisplay.tsxtypescript
"use client"
import { useState } from "react"
import { orpc } from "../../client"
export default function TimeDisplay() {
const [time, setTime] = useState<number | null>(null)
async function refresh() {
setTime(await orpc.time.getCurrent())
}
return (
<div>
<p>{time ?? "—"}</p>
<button onClick={refresh}>Refresh</button>
</div>
)
}Type inference is automaticThe client type is inferred from the router, so procedure arguments and return values are fully typed across the client and server without generating any code.