Context in oRPC 
oRPC's context mechanism provides a type-safe dependency injection pattern. It lets you supply required dependencies either explicitly or dynamically through middleware. There are two types:
- Initial Context: Provided explicitly when invoking a procedure.
- Execution Context: Generated during procedure execution, typically by middleware.
Initial Context 
Initial context is used to define required dependencies (usually environment-specific) that must be passed when calling a procedure.
const base = os.$context<{ headers: Headers, env: { DB_URL: string } }>()
const getting = base
  .handler(async ({ context }) => {
    console.log(context.env)
  })
export const router = { getting }When calling that requires initial context, pass it explicitly:
import { RPCHandler } from '@orpc/server/fetch'
const handler = new RPCHandler(router)
export default function fetch(request: Request) {
  handler.handle(request, {
    context: { // <-- you must pass initial context here
      headers: request.headers,
      env: {
        DB_URL: '***'
      }
    }
  })
}Execution context 
Execution context is computed during the process lifecycle, usually via middleware. It can be used independently or combined with initial context.
import { cookies, headers } from 'next/headers'
const base = os.use(async ({ next }) => next({
  context: {
    headers: await headers(),
    cookies: await cookies(),
  },
}))
const getting = base.handler(async ({ context }) => {
  context.cookies.set('key', 'value')
})
export const router = { getting }When using execution context, you don't need to pass any context manually:
import { RPCHandler } from '@orpc/server/fetch'
const handler = new RPCHandler(router)
export default function fetch(request: Request) {
  handler.handle(request) // <-- no need to pass anything more
}Combining Initial and Execution Context 
Often you need both static and dynamic dependencies. Use initial context for environment-specific values (e.g., database URLs) and middleware (execution context) for runtime data (e.g., user authentication).
const base = os.$context<{ headers: Headers, env: { DB_URL: string } }>()
const requireAuth = base.middleware(async ({ context, next }) => {
  const user = parseJWT(context.headers.get('authorization')?.split(' ')[1])
  if (user) {
    return next({ context: { user } })
  }
  throw new ORPCError('UNAUTHORIZED')
})
const dbProvider = base.middleware(async ({ context, next }) => {
  const client = new Client(context.env.DB_URL)
  try {
    await client.connect()
    return next({ context: { db: client } })
  }
  finally {
    await client.disconnect()
  }
})
const getting = base
  .use(dbProvider)
  .use(requireAuth)
  .handler(async ({ context }) => {
    console.log(context.db)
    console.log(context.user)
  })
