Skip to main content
Use .provide(tag, fn) when a service depends on the current request. Providers can be generator callbacks, Effect.fn(...) callbacks, or functions that return an Effect. Common examples:
  • current user
  • request ID
  • tenant ID
  • authorization scope
  • locale

Provide from context

current-user.ts
import { Context, Effect } from "effect";

class CurrentUser extends Context.Service<
  CurrentUser,
  { readonly id: string; readonly role: "admin" | "member" }
>()("CurrentUser") {}

const authedProcedure = eos
  .provide(AppLive)
  .$context<{ user: { id: string; role: "admin" | "member" } }>()
  .provide(CurrentUser, ({ context }) => Effect.succeed(context.user));

const me = authedProcedure.effect(function* () {
  return yield* CurrentUser;
});

Provide from input

Providers can also use parsed input.
tenant.ts
class TenantId extends Context.Service<TenantId, string>()("TenantId") {}

const tenantProcedure = eos
  .provide(AppLive)
  .input(z.object({ tenantId: z.string() }))
  .provide(TenantId, ({ input }) => Effect.succeed(input.tenantId))
  .effect(function* () {
    const tenantId = yield* TenantId;
    const projectsRepo = yield* ProjectsRepo;
    return yield* projectsRepo.listForTenant(tenantId);
  });

Provider callback shapes

Request-scoped providers can be generator callbacks, Effect.fn(...) callbacks, or functions that return an Effect.
provider-shapes.ts
const authedProcedure = eos.$context<{ user: User }>().provide(
  CurrentUser,
  Effect.fn("current-user.resolve")(function* ({ context }) {
    yield* Effect.logDebug("resolving current user");
    return context.user;
  }),
);

Optional providers

Use .provideOptional(...) when a service may be absent. The provider returns an Option and does not satisfy required service access. Optional providers support the same generator and Effect-returning callback shapes.
optional-current-user.ts
import { Option } from "effect";

const maybeAuthed = eos
  .$context<{ user?: { id: string } }>()
  .provideOptional(CurrentUser, ({ context }) =>
    Effect.succeed(Option.fromNullishOr(context.user)),
  )
  .effect(function* () {
    return yield* Effect.serviceOption(CurrentUser);
  });
Optional providers are useful for anonymous-or-authenticated routes. If a handler requires the service, use .provide(...) instead.

Next step

Add client-visible failures with Typed errors.
Last modified on June 15, 2026