Skip to main content

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.

oRPC integrates with React Server Actions on Next.js, TanStack Start, and other platforms that support the pattern.

.actionable()

Call .actionable() on any procedure to produce a function compatible with the Server Action calling convention. It wraps the call in a try/catch and returns [error, data] tuples instead of throwing:
// app/actions/planet.ts
'use server'

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

export const createPlanet = os
  .input(z.object({ name: z.string() }))
  .handler(async ({ input }) => {
    return { id: 1, name: input.name }
  })
  .actionable()
On the client:
import { createPlanet } from './actions/planet'

async function handleSubmit() {
  const [error, data] = await createPlanet({ name: 'Mars' })

  if (error) {
    console.error('Error code:', error.code)
    return
  }

  console.log('Created:', data)
}

ActionableClientResult

The return type of an actionable procedure is [error: null, data: TOutput] | [error: ErrorJSON, data: undefined]. When error is non-null, it is an ORPCErrorJSON object with:
PropertyDescription
codeThe error code string
statusHTTP status number
messageHuman-readable error message
dataOptional structured data from .errors()
definedtrue if the error was declared in the error map

@orpc/reactorpcAction

For integration with TanStack Query’s useMutation, @orpc/react provides orpcAction:
import { orpcAction } from '@orpc/react'

// Converts an actionable procedure to a standard async function
// that throws on error instead of returning tuples
const action = orpcAction(createPlanet)

// Use with useMutation
const mutation = useMutation({ mutationFn: action })

Special framework errors

Server Actions have special error types for redirects and not-found responses. oRPC detects and re-throws these automatically so framework navigation features work correctly:
  • Next.js: error.digest?.startsWith('NEXT_') errors are re-thrown.
  • TanStack Router: Response instances with options property and { isNotFound: true } objects are re-thrown.

With context

For procedures that require context (e.g., authentication), pass the context factory in .actionable():
export const createPlanet = os
  .$context<{ userId: string }>()
  .input(z.object({ name: z.string() }))
  .handler(async ({ input, context }) => {
    return { id: 1, name: input.name, createdBy: context.userId }
  })
  .actionable({
    context: async () => {
      const session = await getServerSession()
      return { userId: session.user.id }
    },
  })

Build docs developers (and LLMs) love