Skip to main content
You can create Effect-aware builders from either a Layer or a ManagedRuntime.

Simple path: provide a layer

Use eos.provide(AppLive) when per-call acquisition is acceptable and you do not need to own runtime shutdown.
layer.ts
const AppLive = Layer.mergeAll(UsersRepo.Default, Cache.Default);

export const effectProcedure = eos.provide(AppLive);

Long-lived resources: own the runtime

Use makeEffectORPC(runtime) when scoped resources should be acquired once and released on application shutdown.
runtime.ts
import { ManagedRuntime } from "effect";
import { makeEffectORPC } from "effect-orpc";

const runtime = ManagedRuntime.make(AppLive);

export const effectProcedure = makeEffectORPC(runtime);

process.on("SIGTERM", async () => {
  await runtime.dispose();
  process.exit(0);
});
Good candidates for a caller-owned runtime:
  • database pools
  • telemetry SDKs
  • HTTP clients with connection pools
  • caches
  • long-lived scoped resources

Wrap an existing oRPC builder

If your application already has an oRPC builder, wrap it:
wrap-builder.ts
const authedOs = os.$context<{ userId: string }>();

const effectAuthedOs = makeEffectORPC(authedOs).provide(AppLive);

Rule of thumb

NeedUse
Small app, examples, simple serviceseos.provide(AppLive)
Shared scoped resources with explicit shutdownmakeEffectORPC(ManagedRuntime.make(AppLive))
Existing oRPC buildermakeEffectORPC(existingBuilder).provide(AppLive)

Next step

Customize spans with Tracing.
Last modified on June 15, 2026