(options: {
readonly config: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
readonly iteration: Ref.Ref<number>
readonly excitement: Ref.Ref<number>
}): Layer.Layer<PollingTag>Accelerating cadence with externally-managed refs for live tuning. Prefer accelerating unless you need runtime parameter changes via refs.
export const const acceleratingWithRefs: (options: {
readonly config: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
readonly iteration: Ref.Ref<number>
readonly excitement: Ref.Ref<number>
}) => Layer.Layer<PollingTag>
Accelerating cadence with externally-managed refs for live tuning.
Prefer
accelerating
unless you need runtime parameter changes via refs.
acceleratingWithRefs = (options: {
readonly config: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
readonly iteration: Ref.Ref<number>
readonly excitement: Ref.Ref<number>
}
options: {
readonly config: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
(property) config: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
config: import RefRef.interface Ref<in out A>A mutable reference that provides atomic read, write, and update operations.
When to use
Use to keep shared mutable state that is read and updated inside Effect
programs.
Details
A Ref is a thread-safe mutable reference type for shared state. It supports
simple read and write operations as well as atomic transformations.
Example (Reading and updating a ref)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
// Create a ref with initial value
const counter = yield* Ref.make(0)
// Read the current value
const value = yield* Ref.get(counter)
console.log(value) // 0
// Update the value atomically
yield* Ref.update(counter, (n) => n + 1)
// Read the updated value
const newValue = yield* Ref.get(counter)
console.log(newValue) // 1
})
The Ref namespace containing type definitions and utilities.
When to use
Use when referring to type members nested under the Ref namespace.
Ref<{
minIntervalMs: numberminIntervalMs: number;
maxIntervalMs: numbermaxIntervalMs: number;
decayK: numberdecayK: number;
}>;
readonly iteration: Ref.Ref<number>(property) iteration: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
iteration: import RefRef.interface Ref<in out A>A mutable reference that provides atomic read, write, and update operations.
When to use
Use to keep shared mutable state that is read and updated inside Effect
programs.
Details
A Ref is a thread-safe mutable reference type for shared state. It supports
simple read and write operations as well as atomic transformations.
Example (Reading and updating a ref)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
// Create a ref with initial value
const counter = yield* Ref.make(0)
// Read the current value
const value = yield* Ref.get(counter)
console.log(value) // 0
// Update the value atomically
yield* Ref.update(counter, (n) => n + 1)
// Read the updated value
const newValue = yield* Ref.get(counter)
console.log(newValue) // 1
})
The Ref namespace containing type definitions and utilities.
When to use
Use when referring to type members nested under the Ref namespace.
Ref<number>;
readonly excitement: Ref.Ref<number>(property) excitement: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
excitement: import RefRef.interface Ref<in out A>A mutable reference that provides atomic read, write, and update operations.
When to use
Use to keep shared mutable state that is read and updated inside Effect
programs.
Details
A Ref is a thread-safe mutable reference type for shared state. It supports
simple read and write operations as well as atomic transformations.
Example (Reading and updating a ref)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
// Create a ref with initial value
const counter = yield* Ref.make(0)
// Read the current value
const value = yield* Ref.get(counter)
console.log(value) // 0
// Update the value atomically
yield* Ref.update(counter, (n) => n + 1)
// Read the updated value
const newValue = yield* Ref.get(counter)
console.log(newValue) // 1
})
The Ref namespace containing type definitions and utilities.
When to use
Use when referring to type members nested under the Ref namespace.
Ref<number>;
}): import LayerLayer.interface Layer<in ROut, out E = never, out RIn = never>A Layer describes how to build one or more services for dependency injection.
When to use
Use to model construction of application services for dependency injection,
especially when services have dependencies, can fail during construction, or
need scoped setup and release.
Details
A Layer<ROut, E, RIn> represents ROut as the services this layer
provides, E as the possible errors during layer construction, and RIn as
the services this layer requires as dependencies.
Layer<import PollingTagPollingTag> =>
import registerPollingLayerregisterPollingLayer(
import LayerLayer.const effect: <unknown, unknown, never, never>(service: Key<unknown, unknown>, effect: Effect.Effect<unknown, never, never>) => Layer.Layer<unknown, never, never> (+1 overload)Constructs a layer from an effect that produces a single service.
When to use
Use when you need to construct a Layer-provided service with an Effect,
dependencies, or scoped resource acquisition.
Details
This allows you to create a Layer from an Effect that produces a service.
The Effect is executed in the scope of the layer, allowing for proper
resource management.
Example (Creating a layer from an effect)
import { Context, Effect, Layer } from "effect"
class Database extends Context.Service<Database, {
readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}
const layer = Layer.effect(Database,
Effect.sync(() => ({
query: (sql: string) => Effect.succeed(`Query: ${sql}`)
}))
)
effect(
import PollingTagPollingTag,
import EffectEffect.const gen: <Effect.Effect<Ref.Ref<Deferred.Deferred<void, never>>, never, never>, PollingService>(f: () => Generator<Effect.Effect<Ref.Ref<Deferred.Deferred<void, never>>, never, never>, PollingService, never>) => Effect.Effect<PollingService, never, never> (+1 overload)Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to use
Use when you want to write effectful code that looks and behaves like
synchronous code, while still handling asynchronous tasks, errors, and complex
control flow such as loops and conditions.
Generator functions work similarly to async/await but keep errors,
requirements, and interruption in the Effect type. You can yield* values
from effects and return the final result at the end.
Example (Sequencing effects with generators)
import { Data, Effect } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function*() {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})
gen(function* () {
const {
config: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
config: const configRef: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
const configRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
configRef,
iteration: Ref.Ref<number>iteration: const iterationRef: Ref.Ref<number>const iterationRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
iterationRef,
excitement: Ref.Ref<number>excitement: const excRef: Ref.Ref<number>const excRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
excRef,
} = options: {
readonly config: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
readonly iteration: Ref.Ref<number>
readonly excitement: Ref.Ref<number>
}
options;
const const wakeRef: Ref.Ref<
Deferred.Deferred<void, never>
>
const wakeRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
wakeRef = yield* import RefRef.const make: <Deferred.Deferred<void, never>>(value: Deferred.Deferred<void, never>) => Effect.Effect<Ref.Ref<Deferred.Deferred<void, never>>, never, never>Creates a new Ref with the specified initial value.
When to use
Use to create a Ref for shared mutable state inside an Effect program.
Example (Creating a ref)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
make<import DeferredDeferred.interface Deferred<in out A, in out E = never>A Deferred represents an asynchronous variable that can be set exactly
once, with the ability for an arbitrary number of fibers to suspend (by
calling Deferred.await) and automatically resume when the variable is set.
When to use
Use to coordinate multiple fibers around a value or failure that will be
supplied exactly once.
Example (Creating a Deferred for inter-fiber communication)
import { Deferred, Effect, Fiber } from "effect"
// Create and use a Deferred for inter-fiber communication
const program = Effect.gen(function*() {
// Create a Deferred that will hold a string value
const deferred: Deferred.Deferred<string> = yield* Deferred.make<string>()
// Fork a fiber that will set the deferred value
const producer = yield* Effect.forkChild(
Effect.gen(function*() {
yield* Effect.sleep("100 millis")
yield* Deferred.succeed(deferred, "Hello, World!")
})
)
// Fork a fiber that will await the deferred value
const consumer = yield* Effect.forkChild(
Effect.gen(function*() {
const value = yield* Deferred.await(deferred)
console.log("Received:", value)
return value
})
)
// Wait for both fibers to complete
yield* Fiber.join(producer)
const result = yield* Fiber.join(consumer)
return result
})
Companion namespace containing type-level metadata for Deferred.
When to use
Use to reference type-level metadata associated with Deferred.
Deferred<void, never>>(
import DeferredDeferred.const makeUnsafe: <void, never>() => Deferred.Deferred<void, never>Creates an empty Deferred synchronously outside the Effect runtime.
When to use
Use to allocate a Deferred synchronously when direct allocation outside
Effect is required.
Example (Creating a Deferred unsafely)
import { Deferred } from "effect"
const deferred = Deferred.makeUnsafe<number>()
console.log(deferred)
makeUnsafe()
);
const const requestWake: Effect.Effect<
void,
never,
never
>
const requestWake: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
requestWake = import EffectEffect.const flatMap: <Deferred.Deferred<void, never>, never, never, boolean, never, never>(self: Effect.Effect<Deferred.Deferred<void, never>, never, never>, f: (a: Deferred.Deferred<void, never>) => Effect.Effect<boolean, never, never>) => Effect.Effect<boolean, never, never> (+1 overload)Chains effects to produce new Effect instances, useful for combining
operations that depend on previous results.
When to use
Use when you need to chain multiple effects, ensuring that each
step produces a new Effect while flattening any nested effects that may
occur.
Details
flatMap lets you sequence effects so that the result of one effect can be
used in the next step. It is similar to flatMap used with arrays but works
specifically with Effect instances, allowing you to avoid deeply nested
effect structures.
Since effects are immutable, flatMap always returns a new effect instead of
changing the original one.
Example (Choosing flatMap syntax variants)
import { Effect, pipe } from "effect"
const myEffect = Effect.succeed(1)
const transformation = (n: number) => Effect.succeed(n + 1)
const flatMappedWithPipe = pipe(myEffect, Effect.flatMap(transformation))
const flatMappedWithDataFirst = Effect.flatMap(myEffect, transformation)
const flatMappedWithMethod = myEffect.pipe(Effect.flatMap(transformation))
Example (Sequencing dependent effects)
import { Data, Effect, pipe } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
// Function to apply a discount safely to a transaction amount
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Chaining the fetch and discount application using `flatMap`
const finalAmount = pipe(
fetchTransactionAmount,
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(finalAmount).then(console.log)
// Output: 95
flatMap(import RefRef.const get: <Deferred.Deferred<void, never>>(self: Ref.Ref<Deferred.Deferred<void, never>>) => Effect.Effect<Deferred.Deferred<void, never>, never, never>Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const wakeRef: Ref.Ref<
Deferred.Deferred<void, never>
>
const wakeRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
wakeRef), (d: Deferred.Deferred<void, never>(parameter) d: {
effect: Effect<A, E>;
resumes: Array<(effect: Effect<A, E>) => void> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
d) =>
import DeferredDeferred.const succeed: <void | undefined, never>(self: Deferred.Deferred<void | undefined, never>, value: void | undefined) => Effect.Effect<boolean> (+1 overload)Attempts to complete the Deferred with the specified value.
When to use
Use to complete a Deferred with a successful value.
Details
Fibers waiting on the Deferred receive the value only if this call
completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Completing a Deferred with a value)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* Deferred.make<number>()
yield* Deferred.succeed(deferred, 42)
const value = yield* Deferred.await(deferred)
console.log(value) // 42
})
succeed(d: Deferred.Deferred<void, never>(parameter) d: {
effect: Effect<A, E>;
resumes: Array<(effect: Effect<A, E>) => void> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
d, var undefinedundefined)
).Pipeable.pipe<Effect.Effect<boolean, never, never>, Effect.Effect<void, never, never>>(this: Effect.Effect<boolean, never, never>, ab: (_: Effect.Effect<boolean, never, never>) => Effect.Effect<void, never, never>): Effect.Effect<void, never, never> (+21 overloads)pipe(import EffectEffect.const asVoid: <A, E, R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<void, E, R>
Maps the success value of an Effect to void, preserving failures.
Example (Discarding success values)
import { Effect } from "effect"
const program = Effect.asVoid(Effect.succeed(42))
Effect.runPromise(program).then(console.log)
// undefined (void)
asVoid);
const const awaitNextTick: Effect.Effect<
void,
never,
never
>
const awaitNextTick: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
awaitNextTick: import EffectEffect.interface Effect<out A, out E = never, out R = never>The Effect interface defines a value that lazily describes a workflow or
job. The workflow requires some context R, and may fail with an error of
type E, or succeed with a value of type A.
When to use
Use when you need to represent a lazy, composable workflow that can require
services, fail with a typed error, or succeed with a typed value.
Details
Effect values model resourceful interaction with the outside world,
including synchronous, asynchronous, concurrent, and parallel interaction.
They use a fiber-based concurrency model, with built-in support for
scheduling, fine-grained interruption, structured concurrency, and high
scalability.
To run an Effect value, you need a Runtime, which is a type that is
capable of executing Effect values.
Effect<void> = import EffectEffect.const gen: <Effect.Effect<void, never, never>, void>(f: () => Generator<Effect.Effect<void, never, never>, void, never>) => Effect.Effect<void, never, never> (+1 overload)Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to use
Use when you want to write effectful code that looks and behaves like
synchronous code, while still handling asynchronous tasks, errors, and complex
control flow such as loops and conditions.
Generator functions work similarly to async/await but keep errors,
requirements, and interruption in the Effect type. You can yield* values
from effects and return the final result at the end.
Example (Sequencing effects with generators)
import { Data, Effect } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function*() {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})
gen(function* () {
const const d: Deferred.Deferred<void, never>const d: {
effect: Effect<A, E>;
resumes: Array<(effect: Effect<A, E>) => void> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
d = import DeferredDeferred.const makeUnsafe: <void, never>() => Deferred.Deferred<void, never>Creates an empty Deferred synchronously outside the Effect runtime.
When to use
Use to allocate a Deferred synchronously when direct allocation outside
Effect is required.
Example (Creating a Deferred unsafely)
import { Deferred } from "effect"
const deferred = Deferred.makeUnsafe<number>()
console.log(deferred)
makeUnsafe<void, never>();
yield* import RefRef.const set: <Deferred.Deferred<void, never>>(self: Ref.Ref<Deferred.Deferred<void, never>>, value: Deferred.Deferred<void, never>) => Effect.Effect<void> (+1 overload)set(const wakeRef: Ref.Ref<
Deferred.Deferred<void, never>
>
const wakeRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
wakeRef, const d: Deferred.Deferred<void, never>const d: {
effect: Effect<A, E>;
resumes: Array<(effect: Effect<A, E>) => void> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
d);
const const n: numbern = yield* import RefRef.const get: <number>(
self: Ref.Ref<number>
) => Effect.Effect<number, never, never>
Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const iterationRef: Ref.Ref<number>const iterationRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
iterationRef);
const const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg = yield* import RefRef.const get: <{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}>(self: Ref.Ref<{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}>) => Effect.Effect<{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}, never, never>
Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const configRef: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
const configRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
configRef);
const const exc: numberexc = yield* import RefRef.const get: <number>(
self: Ref.Ref<number>
) => Effect.Effect<number, never, never>
Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const excRef: Ref.Ref<number>const excRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
excRef);
const const ms: numberms = const delayMsForIteration: (
fastestMs: number,
slowestMs: number,
decay: number,
excitement: number,
iteration: number
) => number
Compute delay for a given iteration using exponential decay:
delay(n) = fastest + (slowest - fastest) * e^(-decay * n * excitement)
delayMsForIteration(
const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg.minIntervalMs: numberminIntervalMs,
const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg.maxIntervalMs: numbermaxIntervalMs,
const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg.decayK: numberdecayK,
const exc: numberexc,
const n: numbern
);
yield* import EffectEffect.const race: <void, never, never, void, never, never>(self: Effect.Effect<void, never, never>, that: Effect.Effect<void, never, never>, options?: {
readonly onWinner?: (options: {
readonly fiber: Fiber<any, any>;
readonly index: number;
readonly parentFiber: Fiber<any, any>;
}) => void;
}) => Effect.Effect<void, never, never> (+1 overload)
Races two effects and returns the first successful result.
Details
If one effect succeeds, the other is interrupted and onWinner can observe the
winning fiber. If both fail, the race fails.
Example (Racing two effects)
import { Console, Duration, Effect } from "effect"
const fastFail = Effect.delay(Effect.fail("fast-fail"), Duration.millis(10))
const slowSuccess = Effect.delay(Effect.succeed("slow-success"), Duration.millis(50))
const program = Effect.gen(function*() {
const result = yield* Effect.race(fastFail, slowSuccess)
yield* Console.log(`winner: ${result}`)
})
Effect.runPromise(program)
// Output: winner: slow-success
race(
import EffectEffect.const sleep: (
duration: Duration.Input
) => Effect.Effect<void>
Returns an effect that suspends the current fiber for the specified duration
without blocking a JavaScript thread.
Example (Pausing without blocking)
import { Console, Effect } from "effect"
const program = Effect.gen(function*() {
yield* Console.log("Start")
yield* Effect.sleep("2 seconds")
yield* Console.log("End")
})
Effect.runFork(program)
// Output: "Start" (immediately)
// Output: "End" (after 2 seconds)
sleep(import DurationDuration.const millis: (
millis: number
) => Duration.Duration
Creates a Duration from milliseconds.
Example (Creating durations from milliseconds)
import { Duration } from "effect"
const duration = Duration.millis(1000)
console.log(Duration.toMillis(duration)) // 1000
millis(const ms: numberms)),
import DeferredDeferred.await<void, never>(self: Deferred.Deferred<void, never>): Effect.Effect<void, never, never>
export await
Retrieves the value of the Deferred, suspending the fiber running the
workflow until the result is available.
When to use
Use to wait for a Deferred to be completed and resume with its success,
failure, defect, or interruption.
Details
Awaiters observe the completion effect stored in the Deferred.
Example (Awaiting a Deferred value)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function*() {
const deferred = yield* Deferred.make<number>()
yield* Deferred.succeed(deferred, 42)
const value = yield* Deferred.await(deferred)
console.log(value) // 42
})
await(const d: Deferred.Deferred<void, never>const d: {
effect: Effect<A, E>;
resumes: Array<(effect: Effect<A, E>) => void> | undefined;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
d)
).Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<void, never, never>>(this: Effect.Effect<void, never, never>, ab: (_: Effect.Effect<void, never, never>) => Effect.Effect<void, never, never>): Effect.Effect<void, never, never> (+21 overloads)pipe(import EffectEffect.const asVoid: <A, E, R>(
self: Effect.Effect<A, E, R>
) => Effect.Effect<void, E, R>
Maps the success value of an Effect to void, preserving failures.
Example (Discarding success values)
import { Effect } from "effect"
const program = Effect.asVoid(Effect.succeed(42))
Effect.runPromise(program).then(console.log)
// undefined (void)
asVoid);
});
const const resetCadence: Effect.Effect<
void,
never,
never
>
const resetCadence: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
resetCadence = import RefRef.const set: <number>(self: Ref.Ref<number>, value: number) => Effect.Effect<void> (+1 overload)set(const iterationRef: Ref.Ref<number>const iterationRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
iterationRef, 0).Pipeable.pipe<Effect.Effect<void, never, never>, Effect.Effect<void, never, never>>(this: Effect.Effect<void, never, never>, ab: (_: Effect.Effect<void, never, never>) => Effect.Effect<void, never, never>): Effect.Effect<void, never, never> (+21 overloads)pipe(
import EffectEffect.const andThen: <void, never, never>(f: Effect.Effect<void, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<void, E, R> (+3 overloads)Runs this effect and then runs another effect, optionally using the first
effect's success value to choose the next effect.
When to use
Use when you need one effect to run after another and the second effect may
depend on the first effect's success value.
Details
When the second argument is an Effect, the first success value is discarded
and the returned effect produces the second effect's value. When the second
argument is a function, it receives the first success value and must return
the next Effect.
Failures or requirements from either effect are preserved in the returned
effect.
Example (Choosing andThen syntax variants)
import { Effect, pipe } from "effect"
const myEffect = Effect.succeed(1)
const anotherEffect = Effect.succeed("done")
const transformedWithPipe = pipe(myEffect, Effect.andThen(anotherEffect))
const transformedWithDataFirst = Effect.andThen(myEffect, anotherEffect)
const transformedWithMethod = myEffect.pipe(Effect.andThen(anotherEffect))
Example (Sequencing a discount calculation after fetching a total)
import { Data, Effect, pipe } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
// Function to apply a discount safely to a transaction amount
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Using Effect.map and Effect.flatMap
const result1 = pipe(
fetchTransactionAmount,
Effect.map((amount) => amount * 2),
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(result1).then(console.log)
// Output: 190
// Using Effect.andThen
const result2 = pipe(
fetchTransactionAmount,
Effect.andThen((amount) => Effect.succeed(amount * 2)),
Effect.andThen((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(result2).then(console.log)
// Output: 190
andThen(const requestWake: Effect.Effect<
void,
never,
never
>
const requestWake: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
requestWake)
);
const const afterTick: Effect.Effect<
void,
never,
never
>
const afterTick: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
afterTick = import RefRef.const update: <number>(self: Ref.Ref<number>, f: (a: number) => number) => Effect.Effect<void> (+1 overload)update(const iterationRef: Ref.Ref<number>const iterationRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
iterationRef, (n: numbern) => n: numbern + 1);
const const peekCadence: Effect.Effect<
Option.Option<Duration.Duration>,
never,
never
>
const peekCadence: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
peekCadence = import EffectEffect.const gen: <Effect.Effect<{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}, never, never> | Effect.Effect<number, never, never>, Option.Option<Duration.Duration>>(f: () => Generator<Effect.Effect<{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}, never, never> | Effect.Effect<number, never, never>, Option.Option<Duration.Duration>, never>) => Effect.Effect<Option.Option<Duration.Duration>, never, never> (+1 overload)
Provides a way to write effectful code using generator functions, simplifying
control flow and error handling.
When to use
Use when you want to write effectful code that looks and behaves like
synchronous code, while still handling asynchronous tasks, errors, and complex
control flow such as loops and conditions.
Generator functions work similarly to async/await but keep errors,
requirements, and interruption in the Effect type. You can yield* values
from effects and return the final result at the end.
Example (Sequencing effects with generators)
import { Data, Effect } from "effect"
class DiscountRateError extends Data.TaggedError("DiscountRateError")<{}> {}
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, DiscountRateError> =>
discountRate === 0
? Effect.fail(new DiscountRateError())
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function*() {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})
gen(function* () {
const const n: numbern = yield* import RefRef.const get: <number>(
self: Ref.Ref<number>
) => Effect.Effect<number, never, never>
Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const iterationRef: Ref.Ref<number>const iterationRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
iterationRef);
const const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg = yield* import RefRef.const get: <{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}>(self: Ref.Ref<{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}>) => Effect.Effect<{
minIntervalMs: number;
maxIntervalMs: number;
decayK: number;
}, never, never>
Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const configRef: Ref.Ref<{
minIntervalMs: number
maxIntervalMs: number
decayK: number
}>
const configRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
configRef);
const const exc: numberexc = yield* import RefRef.const get: <number>(
self: Ref.Ref<number>
) => Effect.Effect<number, never, never>
Gets the current value of the Ref.
When to use
Use to read the current Ref value without changing it.
Example (Getting the current value)
import { Effect, Ref } from "effect"
const program = Effect.gen(function*() {
const ref = yield* Ref.make(42)
const value = yield* Ref.get(ref)
console.log(value) // 42
})
get(const excRef: Ref.Ref<number>const excRef: {
ref: MutableRef.MutableRef<A>;
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
}
excRef);
return import OptionOption.const some: <Duration.Duration>(value: Duration.Duration) => Option.Option<Duration.Duration>Wraps the given value into an Option to represent its presence.
When to use
Use to wrap a known present value as Option
- Returning a successful result from a partial function
Details
- Always returns
Some<A>
- Does not filter
null or undefined; use
fromNullishOr
for that
Example (Wrapping a value)
import { Option } from "effect"
// ┌─── Option<number>
// ▼
const value = Option.some(1)
console.log(value)
// Output: { _id: 'Option', _tag: 'Some', value: 1 }
some(
import DurationDuration.const millis: (
millis: number
) => Duration.Duration
Creates a Duration from milliseconds.
Example (Creating durations from milliseconds)
import { Duration } from "effect"
const duration = Duration.millis(1000)
console.log(Duration.toMillis(duration)) // 1000
millis(
const delayMsForIteration: (
fastestMs: number,
slowestMs: number,
decay: number,
excitement: number,
iteration: number
) => number
Compute delay for a given iteration using exponential decay:
delay(n) = fastest + (slowest - fastest) * e^(-decay * n * excitement)
delayMsForIteration(
const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg.minIntervalMs: numberminIntervalMs,
const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg.maxIntervalMs: numbermaxIntervalMs,
const cfg: {
minIntervalMs: number
maxIntervalMs: number
decayK: number
}
cfg.decayK: numberdecayK,
const exc: numberexc,
const n: numbern
)
)
);
});
return {
awaitNextTick: Effect.Effect<void, never, never>(property) awaitNextTick: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
awaitNextTick,
requestWake: Effect.Effect<void, never, never>(property) requestWake: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
requestWake,
resetCadence: Effect.Effect<void, never, never>(property) resetCadence: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
resetCadence,
afterTick: Effect.Effect<void, never, never>(property) afterTick: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
afterTick,
peekCadence: Effect.Effect<
Option.Option<Duration.Duration>,
never,
never
>
(property) peekCadence: {
pipe: { <A>(this: A): A; <A, B = never>(this: A, ab: (_: A) => B): B; <A, B = never, C = never>(this: A, ab: (_: A) => B, bc: (_: B) => C): C; <A, B = never, C = never, D = never>(this: A, ab: (_: A) => B, bc: (_: B) => C, cd: (_: C) => D): D; <…;
toString: () => string;
toJSON: () => unknown;
}
peekCadence,
} satisfies import PollingServicePollingService;
})
)
);