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
| 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
Read Guide →