Documentation Index
Fetch the complete documentation index at: https://mintlify.com/middleapi/orpc/llms.txt
Use this file to discover all available pages before exploring further.
createORPCClient
createORPCClient(link, options?) creates a proxy object that mirrors your router’s shape. Every property access on the proxy builds up a path, and calling the resulting function dispatches a request through the provided link.
import type { RouterClient } from '@orpc/server'
import { createORPCClient } from '@orpc/client'
import { RPCLink } from '@orpc/client/fetch'
import type { router } from './server'
const link = new RPCLink({
url: 'http://localhost:3000/rpc',
})
export const orpc: RouterClient<typeof router> = createORPCClient(link)
Type parameter
Pass RouterClient<typeof router> (from @orpc/server) as the type argument so TypeScript can infer exact input, output, and error types for every procedure.
import type { RouterClient } from '@orpc/server'
import type { router } from './server'
// orpc is fully typed — inputs, outputs and errors are all inferred
const orpc: RouterClient<typeof router> = createORPCClient(link)
Calling procedures
The proxy mirrors your router shape. Property accesses are chainable, and the final call sends the request:
// planet.list
const planets = await orpc.planet.list({ limit: 10 })
// planet.find
const planet = await orpc.planet.find({ id: 1 })
// planet.create — TypeScript will error if you omit required fields
const created = await orpc.planet.create({ name: 'Mars', description: 'Red planet' })
Each call accepts an optional second argument for client options:
const planets = await orpc.planet.list(
{ limit: 10 },
{
signal: abortController.signal, // cancel inflight requests
context: { token: 'my-token' }, // pass context to the link
},
)
Base path option
If you only want to expose a subset of your router, pass a path option:
import type { RouterClient } from '@orpc/server'
import type { router } from './server'
// This client only knows about the planet sub-router
const planetClient: RouterClient<typeof router.planet> = createORPCClient(link, {
path: ['planet'],
})
const planets = await planetClient.list({ limit: 10 })
createSafeClient
createSafeClient(client) wraps every procedure call in the safe() helper so that calls never throw. Instead they return a SafeResult tuple — or object — with error, data, isDefined, and isSuccess fields.
import { createORPCClient, createSafeClient } from '@orpc/client'
const orpc = createORPCClient<RouterClient<typeof router>>(link)
const safeOrpc = createSafeClient(orpc)
const result = await safeOrpc.planet.list({ limit: 10 })
if (result.error) {
// result.error is typed
console.error(result.error.message)
} else {
// result.data is typed as the procedure output
console.log(result.data)
}
The result supports both tuple-style and object-style access:
// Tuple style
const [error, data, isDefined, isSuccess] = await safeOrpc.planet.list({ limit: 10 })
// Object style
const { error, data, isDefined, isSuccess } = await safeOrpc.planet.list({ limit: 10 })
See Error handling for details on isDefined and typed errors.
The .func pattern
Because the client is a Proxy, calling .call on a procedure utils gives you the underlying function directly — useful when passing it to higher-order utilities:
import { createRouterUtils } from '@orpc/tanstack-query'
const utils = createRouterUtils(orpc)
// utils.planet.list.call is the raw client function
const fn = utils.planet.list.call
const planets = await fn({ limit: 10 })
Inferring types
Several utility types let you extract types from a client without needing the server source:
import type {
InferClientInputs,
InferClientOutputs,
InferClientErrors,
} from '@orpc/client'
import type { orpc } from './client'
type Inputs = InferClientInputs<typeof orpc>
type PlanetListInput = Inputs['planet']['list']
// { limit?: number; cursor?: number }
type Outputs = InferClientOutputs<typeof orpc>
type PlanetListOutput = Outputs['planet']['list']