Skip to content
Back to skills

Orpc Migrate From Trpc

ASecurity

A comprehensive guide to migrate your tRPC application to oRPC.

  • 8 stars
  • 0 votes
  • 1 copy
  • 2 views
  • Added September 12, 2026
databasesreactnextjsawsgitapi

Works with

  • cursor
  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 12, 2026

npx -y skills add ali-master/skills --skill orpc-migrate-from-trpc --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Orpc Migrate From Trpc?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Orpc Migrate From Trpc
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ali-master-orpc-migrate-from-trpc/badge)](https://www.skillsdirectory.com/skills/ali-master-orpc-migrate-from-trpc)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: oRPC Migrate from tRPC
description: A comprehensive guide to migrate your tRPC application to oRPC.
license: MIT
metadata:
  author: Ali Torki
  homepage: https://github.com/ali-master
  version: "1.0.0"
---

# Migrating from tRPC

oRPC draws significant inspiration from tRPC, making migration straightforward.

> For quick enhancement without full migration, see [tRPC Integration](/docs/openapi/integrations/trpc).

## Core Concepts Comparison

| Concept                 | tRPC                         | oRPC                |
| ----------------------- | ---------------------------- | ------------------- |
| Router                  | `t.router()`                 | an object           |
| Procedure               | `t.procedure`                | `os`                |
| Context                 | `t.context()`                | `os.$context()`     |
| Create Middleware       | `t.middleware()`             | `os.middleware()`   |
| Use Middleware          | `t.procedure.use()`          | `os.use()`          |
| Input Validation        | `t.procedure.input(schema)`  | `os.input(schema)`  |
| Output Validation       | `t.procedure.output(schema)` | `os.output(schema)` |
| Error Handling          | `TRPCError`                  | `ORPCError`         |
| Serializer              | `superjson`                  | built-in            |

## Step-by-Step Migration

### 1. Installation

```sh
npm uninstall @trpc/server @trpc/client @trpc/tanstack-react-query
npm install @orpc/server@latest @orpc/client@latest @orpc/tanstack-query@latest
```

### 2. Initialize

```ts
import { ORPCError, os } from '@orpc/server'

export async function createRPCContext(opts: { headers: Headers }) {
  const session = await auth()
  return { headers: opts.headers, session }
}

const o = os.$context<Awaited<ReturnType<typeof createRPCContext>>>()

const timingMiddleware = o.middleware(async ({ next, path }) => {
  const start = Date.now()
  try {
    return await next()
  } finally {
    console.log(`[oRPC] ${path} took ${Date.now() - start}ms`)
  }
})

export const publicProcedure = o.use(timingMiddleware)

export const protectedProcedure = publicProcedure.use(({ context, next }) => {
  if (!context.session?.user) {
    throw new ORPCError('UNAUTHORIZED')
  }
  return next({
    context: { session: { ...context.session, user: context.session.user } }
  })
})
```

### 3. Procedures

In oRPC there are no separate `.query`/`.mutation`/`.subscription` methods. Use `.handler` for all procedure types.

```ts
export const planetRouter = {
  list: publicProcedure
    .input(z.object({ cursor: z.number().int().default(0) }))
    .handler(({ input }) => {
      return { planets: [], nextCursor: input.cursor + 1 }
    }),

  create: protectedProcedure
    .input(z.object({
      name: z.string().min(1),
      distanceFromSun: z.number().positive()
    }))
    .handler(async ({ context, input }) => {}),
}
```

### 4. App Router

In oRPC you don't need to wrap routers — plain objects are enough:

```ts
export const appRouter = {
  planet: planetRouter,
}
```

### 5. Error Handling

```ts
throw new ORPCError('BAD_REQUEST', {
  message: 'Invalid input',
  data: 'some data',
  cause: validationError
})
```

### 6. Server Setup (Next.js)

```ts
// app/api/orpc/[[...rest]]/route.ts
import { RPCHandler } from '@orpc/server/fetch'

const handler = new RPCHandler(appRouter, {
  interceptors: [
    async ({ next }) => {
      try { return await next() }
      catch (error) { console.error(error); throw error }
    }
  ]
})

async function handleRequest(request: Request) {
  const { response } = await handler.handle(request, {
    prefix: '/api/orpc',
    context: await createORPCContext(request)
  })
  return response ?? new Response('Not found', { status: 404 })
}

export const GET = handleRequest
export const POST = handleRequest
```

### 7. Client Setup

```ts
import { createORPCClient, onError } from '@orpc/client'
import { RPCLink } from '@orpc/client/fetch'

const link = new RPCLink({
  url: 'http://localhost:3000/api/orpc',
  interceptors: [onError(e => console.error(e))],
})

export const client: RouterClient<typeof appRouter> = createORPCClient(link)

// Usage:
const { planets } = await client.planet.list({ cursor: 0 })
```

### 8. TanStack Query Integration

```ts
import { createTanstackQueryUtils } from '@orpc/tanstack-query'

export const orpc = createTanstackQueryUtils(client)

// Usage:
const query = useQuery(orpc.planet.list.queryOptions({ input: { cursor: 0 } }))
const mutation = useMutation(orpc.planet.create.mutationOptions())
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.