Documentation Index
Fetch the complete documentation index at: https://mintlify.com/effect-TS/effect-smol/llms.txt
Use this file to discover all available pages before exploring further.
This module provides utilities for working with Fiber, the fundamental unit of concurrency in Effect. Fibers are lightweight, user-space threads that allow multiple Effects to run concurrently with structured concurrency guarantees.
Overview
Fibers are the building blocks of concurrent programming in Effect:
- Lightweight: Much lighter than OS threads, you can create millions
- Structured concurrency: Parent fibers manage child fiber lifecycles
- Cancellation safety: Proper resource cleanup when interrupted
- Cooperative: Fibers yield control at effect boundaries
- Traceable: Each fiber has an ID for debugging and monitoring
Basic Usage
import { Console, Effect, Fiber } from "effect"
// Fork an effect to run concurrently
const program = Effect.gen(function*() {
const fiber = yield* Effect.forkChild(
Effect.gen(function*() {
yield* Effect.sleep("2 seconds")
yield* Console.log("Background task completed")
return "background result"
})
)
// Do other work while the fiber runs
yield* Console.log("Doing other work...")
yield* Effect.sleep("1 second")
// Wait for the fiber to complete
const result = yield* Fiber.join(fiber)
yield* Console.log(`Fiber result: ${result}`)
})
Types
Fiber
interface Fiber<out A, out E = never>
A runtime fiber that executes Effects. Provides:
id: Unique fiber identifier
currentOpCount: Number of operations executed
services: Service context for the fiber
currentScheduler: Scheduler managing the fiber
Creating Fibers
Fibers are typically created using Effect.forkChild:
const fiber = yield* Effect.forkChild(myEffect)
Joining Fibers
join
const join: <A, E>(self: Fiber<A, E>) => Effect<A, E>
Waits for a fiber to complete and returns its result. If the fiber fails, the error is propagated.
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const fiber = yield* Effect.forkChild(Effect.succeed(42))
const result = yield* Fiber.join(fiber)
console.log(result) // 42
})
await
const await: <A, E>(self: Fiber<A, E>) => Effect<Exit<A, E>>
Waits for a fiber to complete and returns its exit value (includes success, failure, or interruption).
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const fiber = yield* Effect.forkChild(Effect.succeed(42))
const exit = yield* Fiber.await(fiber)
console.log(exit) // Exit.succeed(42)
})
joinAll
const joinAll: <A extends Iterable<Fiber<any, any>>>(
self: A
) => Effect<...>
Joins multiple fibers, returning all their results.
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const fiber1 = yield* Effect.forkChild(Effect.succeed(1))
const fiber2 = yield* Effect.forkChild(Effect.succeed(2))
const [result1, result2] = yield* Fiber.joinAll([fiber1, fiber2])
console.log(result1, result2) // 1, 2
})
Interrupting Fibers
interrupt
const interrupt: <A, E>(self: Fiber<A, E>) => Effect<void>
Interrupts a fiber, causing it to stop executing and clean up resources.
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const fiber = yield* Effect.forkChild(
Effect.delay("1 second")(Effect.succeed(42))
)
yield* Fiber.interrupt(fiber)
console.log("Fiber interrupted")
})
interruptAs
const interruptAs: {
(fiberId: number | undefined): <A, E>(self: Fiber<A, E>) => Effect<void>
<A, E>(self: Fiber<A, E>, fiberId: number | undefined): Effect<void>
}
Interrupts a fiber with a specific fiber ID as the interruptor.
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const targetFiber = yield* Effect.forkChild(
Effect.delay("5 seconds")(Effect.succeed("task completed"))
)
// Interrupt the fiber, specifying fiber ID 123 as the interruptor
yield* Fiber.interruptAs(targetFiber, 123)
console.log("Fiber interrupted by fiber #123")
})
interruptAll
const interruptAll: <A extends Iterable<Fiber<any, any>>>(
fibers: A
) => Effect<void>
Interrupts all fibers in the provided iterable.
import { Console, Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const fiber1 = yield* Effect.forkChild(
Effect.gen(function*() {
yield* Effect.sleep("5 seconds")
yield* Console.log("Task 1 completed")
})
)
const fiber2 = yield* Effect.forkChild(
Effect.gen(function*() {
yield* Effect.sleep("3 seconds")
yield* Console.log("Task 2 completed")
})
)
// Interrupt all fibers
yield* Effect.sleep("1 second")
yield* Fiber.interruptAll([fiber1, fiber2])
yield* Console.log("All fibers interrupted")
})
Utilities
isFiber
const isFiber: (u: unknown) => u is Fiber<unknown, unknown>
Type guard to check if a value is a Fiber.
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const fiber = yield* Effect.forkChild(Effect.succeed(42))
console.log(Fiber.isFiber(fiber)) // true
console.log(Fiber.isFiber("hello")) // false
})
getCurrent
const getCurrent: () => Fiber<any, any> | undefined
Returns the current fiber if called from within a fiber context.
import { Effect, Fiber } from "effect"
const program = Effect.gen(function*() {
const current = Fiber.getCurrent()
if (current) {
console.log(`Current fiber ID: ${current.id}`)
}
})
Common Patterns
Fork and Join
Start concurrent work and wait for results:
import { Effect, Fiber } from "effect"
const parallelExample = Effect.gen(function*() {
const task1 = Effect.delay(Effect.succeed("task1"), "1 second")
const task2 = Effect.delay(Effect.succeed("task2"), "2 seconds")
const fiber1 = yield* Effect.forkChild(task1)
const fiber2 = yield* Effect.forkChild(task2)
const result1 = yield* Fiber.join(fiber1)
const result2 = yield* Fiber.join(fiber2)
return [result1, result2] // ["task1", "task2"]
})
Parallel Execution
Run multiple tasks concurrently:
import { Effect } from "effect"
const parallelExample = Effect.gen(function*() {
const tasks = [1, 2, 3, 4, 5].map((n) =>
Effect.gen(function*() {
yield* Effect.sleep(`${n * 100} millis`)
return n * n
})
)
// Run all tasks in parallel
const results = yield* Effect.all(tasks, { concurrency: "unbounded" })
return results // [1, 4, 9, 16, 25]
})
Scope Management
runIn
const runIn: {
(scope: Scope): <A, E>(self: Fiber<A, E>) => Fiber<A, E>
<A, E>(self: Fiber<A, E>, scope: Scope): Fiber<A, E>
}
Links the lifetime of a fiber to a provided scope.