Effect Cheat Sheet

Quick reference for Effect (Effect-TS): creating effects, error handling, services, layers, and concurrency. Build robust TypeScript applications with type-safe effects.

Creating Effects Pipes & Composition Error Handling Services & Layers Concurrency

Creating Effects

Effect.succeed(42) Create an effect that succeeds with value 42
Effect.fail(new Error("oops")) Create an effect that fails with an error
Effect.sync(() => Date.now()) Wrap a synchronous side effect
Effect.tryPromise(() => fetch("/api")) Wrap a Promise-returning function into an Effect
Effect.gen(function* () { const a = yield* getUser; return a.name; }) Generator syntax for sequential effect composition

Pipes & Composition

pipe(effect, Effect.map(x => x + 1)) Transform the success value of an effect
pipe(effect, Effect.flatMap(x => fetchItem(x))) Chain effects sequentially (like async/await)
pipe(effect, Effect.tap(x => Effect.log(`got ${x}`))) Run a side effect without changing the value
Effect.all([effectA, effectB]) Run multiple effects in parallel, collect all results
effect.pipe(Effect.map(f), Effect.flatMap(g)) Method-style piping (alternative to pipe function)

Error Handling

pipe(effect, Effect.catchAll(err => Effect.succeed(fallback))) Catch all errors and provide a fallback value
pipe(effect, Effect.catchTag("NotFound", () => Effect.succeed(null))) Catch a specific tagged error class
class NotFound extends Data.TaggedError("NotFound")<{ id: string }> {} Define a typed, tagged error class
pipe(effect, Effect.retry(Schedule.exponential("1 second"))) Retry a failing effect with exponential backoff
pipe(effect, Effect.orElse(() => alternativeEffect)) Try alternative effect if first one fails

Services & Layers

class Database extends Context.Tag("Database")<Database, { query: (sql: string) => Effect.Effect<Row[]> }>() {} Define a service tag with its interface
const DatabaseLive = Layer.succeed(Database, { query: (sql) => Effect.succeed([]) }) Create a live implementation layer for a service
const result = yield* Database Access a service inside Effect.gen
pipe(program, Effect.provide(DatabaseLive)) Provide a layer to satisfy service dependencies
const AppLive = Layer.merge(DatabaseLive, LoggerLive) Combine multiple layers into one

Concurrency

Effect.all(effects, { concurrency: 5 }) Run effects with bounded concurrency (max 5 at once)
Effect.race(effectA, effectB) Return the result of whichever effect completes first
Effect.timeout(effect, "5 seconds") Fail if the effect does not complete within timeout
Effect.forEach(items, (item) => process(item), { concurrency: "unbounded" }) Process items concurrently with no limit
const fiber = yield* Effect.fork(backgroundTask) Fork an effect into a background fiber
Step-by-Step Guide

How to Format JSON Online

Read Guide →

More Cheat Sheets