Skip to main content

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.