Skip to main content
The Context module provides a data structure for dependency injection in effectful programs. It’s a type-safe table mapping Tags to their service implementations.

Types

Context

interface Context<in Services>
A context is a collection of services indexed by tags.
Services
type parameter
The union of service identifiers available in this context

Tag

interface Tag<in out Id, in out Value>
A tag identifies a service in the context.
Id
type parameter
The unique identifier for this service
Value
type parameter
The service implementation type

Constructors

empty

Returns an empty Context.
const empty: () => Context<never>
return
Context<never>
An empty context with no services
import { Context } from "effect"

const ctx = Context.empty()

make

Creates a new Context with a single service.
const make: <I, S>(tag: Tag<I, S>, service: S) => Context<I>
tag
Tag<I, S>
required
The service tag
service
S
required
The service implementation
return
Context<I>
A context containing the single service
import { Context } from "effect"

const Port = Context.GenericTag<{ PORT: number }>("Port")
const ctx = Context.make(Port, { PORT: 8080 })

GenericTag

Creates a new Tag with an optional key parameter.
const GenericTag: <Identifier, Service = Identifier>(key: string) => Tag<Identifier, Service>
key
string
required
The unique key for this tag
return
Tag<Identifier, Service>
A new tag instance
import { Context } from "effect"

const Database = Context.GenericTag<{ query: (sql: string) => string }>("Database")

Tag

Creates a tag class for defining services.
const Tag: <const Id extends string>(id: Id) => <Self, Shape>() => TagClass<Self, Id, Shape>
id
string
required
The unique identifier for the tag
return
TagClass constructor
A tag class that can be extended
import { Context } from "effect"

class MyService extends Context.Tag("MyService")<
  MyService,
  { readonly value: number }
>() {}

Reference

Creates a context tag with a default value.
const Reference: <Self>() => <const Id extends string, Service>(
  id: Id,
  options: { readonly defaultValue: () => Service }
) => ReferenceClass<Self, Id, Service>
id
string
required
The unique identifier
options.defaultValue
() => Service
required
Function providing the default value
return
ReferenceClass
A reference that provides a default value
import { Context, Effect } from "effect"

class SpecialNumber extends Context.Reference<SpecialNumber>()(
  "SpecialNumber",
  { defaultValue: () => 2048 }
) {}

const program = Effect.gen(function* () {
  const num = yield* SpecialNumber
  console.log(num) // 2048
})
References are useful for optional services that have sensible defaults.

Operations

add

Adds a service to a context.
const add: {
  <I, S>(tag: Tag<I, S>, service: S): <Services>(self: Context<Services>) => Context<Services | I>
  <Services, I, S>(self: Context<Services>, tag: Tag<I, S>, service: S): Context<Services | I>
}
self
Context<Services>
required
The existing context
tag
Tag<I, S>
required
The service tag
service
S
required
The service implementation
return
Context<Services | I>
A new context with the added service
import { Context, pipe } from "effect"

const Port = Context.GenericTag<{ PORT: number }>("Port")
const Timeout = Context.GenericTag<{ TIMEOUT: number }>("Timeout")

const ctx = pipe(
  Context.make(Port, { PORT: 8080 }),
  Context.add(Timeout, { TIMEOUT: 5000 })
)

get

Retrieves a service from the context.
const get: {
  <I, S>(tag: Reference<I, S>): <Services>(self: Context<Services>) => S
  <Services, I extends Services, S>(tag: Tag<I, S>): (self: Context<Services>) => S
  <Services, I, S>(self: Context<Services>, tag: Reference<I, S>): S
  <Services, I extends Services, S>(self: Context<Services>, tag: Tag<I, S>): S
}
self
Context<Services>
required
The context to get from
tag
Tag<I, S>
required
The tag identifying the service
return
S
The service implementation
import { Context } from "effect"

const Port = Context.GenericTag<{ PORT: number }>("Port")
const ctx = Context.make(Port, { PORT: 8080 })

const port = Context.get(ctx, Port)
// { PORT: 8080 }

getOption

Retrieves a service wrapped in an Option.
const getOption: {
  <S, I>(tag: Tag<I, S>): <Services>(self: Context<Services>) => Option<S>
  <Services, S, I>(self: Context<Services>, tag: Tag<I, S>): Option<S>
}
self
Context<Services>
required
The context to get from
tag
Tag<I, S>
required
The tag identifying the service
return
Option<S>
Some(service) if present, None otherwise
import { Context, Option } from "effect"

const Port = Context.GenericTag<{ PORT: number }>("Port")
const ctx = Context.empty()

const maybePort = Context.getOption(ctx, Port)
// Option.none()

merge

Merges two contexts.
const merge: {
  <R1>(that: Context<R1>): <Services>(self: Context<Services>) => Context<R1 | Services>
  <Services, R1>(self: Context<Services>, that: Context<R1>): Context<Services | R1>
}
self
Context<Services>
required
The first context
that
Context<R1>
required
The second context
return
Context<Services | R1>
A context containing services from both
import { Context } from "effect"

const Port = Context.GenericTag<{ PORT: number }>("Port")
const Timeout = Context.GenericTag<{ TIMEOUT: number }>("Timeout")

const ctx1 = Context.make(Port, { PORT: 8080 })
const ctx2 = Context.make(Timeout, { TIMEOUT: 5000 })

const merged = Context.merge(ctx1, ctx2)

pick

Returns a new Context containing only specified services.
const pick: <Tags extends ReadonlyArray<Tag<any, any>>>(
  ...tags: Tags
) => <Services>(self: Context<Services>) => Context<Services & Tag.Identifier<Tags[number]>>
tags
Tag[]
required
The tags to keep
self
Context<Services>
required
The source context
return
Context<...>
A context with only the picked services
import { Context, pipe } from "effect"

const Port = Context.GenericTag<{ PORT: number }>("Port")
const Timeout = Context.GenericTag<{ TIMEOUT: number }>("Timeout")

const ctx = pipe(
  Context.make(Port, { PORT: 8080 }),
  Context.add(Timeout, { TIMEOUT: 5000 })
)

const onlyPort = pipe(ctx, Context.pick(Port))

omit

Returns a new Context excluding specified services.
const omit: <Tags extends ReadonlyArray<Tag<any, any>>>(
  ...tags: Tags
) => <Services>(self: Context<Services>) => Context<Exclude<Services, Tag.Identifier<Tags[number]>>>

Guards

isContext

Checks if a value is a Context.
const isContext: (input: unknown) => input is Context<never>
input
unknown
required
The value to check
return
boolean
true if the value is a Context
import { Context } from "effect"

Context.isContext(Context.empty()) // true
Context.isContext({}) // false

isTag

Checks if a value is a Tag.
const isTag: (input: unknown) => input is Tag<any, any>

isReference

Checks if a value is a Reference.
const isReference: (u: unknown) => u is Reference<any, any>

Build docs developers (and LLMs) love