Skip to content

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.

ts
const  = .<{ : Headers, : { : string } }>()

const  = 
  .(async ({  }) => {
    .(.)
  })

export const  = {  }

When calling that requires initial context, pass it explicitly:

ts
import {  } from '@orpc/server/fetch'

const  = new ()

export default function (: Request) {
  .(, {
    : { // <-- you must pass initial context here
      : .,
      : {
        : '***'
      }
    }
  })
}

Execution context

Execution context is computed during the process lifecycle, usually via middleware. It can be used independently or combined with initial context.

ts
import { ,  } from 'next/headers'

const  = .(async ({  }) => ({
  : {
    : await (),
    : await (),
  },
}))

const  = .(async ({  }) => {
  ..('key', 'value')
})

export const  = {  }

When using execution context, you don't need to pass any context manually:

ts
import {  } from '@orpc/server/fetch'

const  = new ()

export default function (: 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).

ts
const  = .<{ : Headers, : { : string } }>()

const  = .(async ({ ,  }) => {
  const  = (..('authorization')?.(' ')[1])

  if () {
    return ({ : {  } })
  }

  throw new ('UNAUTHORIZED')
})

const  = .(async ({ ,  }) => {
  const  = new (..)

  try {
    await .()
    return ({ : { :  } })
  }
  finally {
    await .()
  }
})

const  = 
  .()
  .()
  .(async ({  }) => {
    .(.)
    .(.)
  })

Released under the MIT License.