{"id":10777,"library":"effect","title":"Effect-TS Core Library","description":"Effect-TS is a robust, type-safe functional programming library for TypeScript, providing a \"missing standard library\" for building highly concurrent, resilient, and performant applications. It centers around the `Effect` data type, which represents a description of a computation that may require resources (R), may fail with an error (E), and may succeed with a value (A). The library promotes a functional-first approach, emphasizing immutability, explicit error handling, and structured concurrency, leveraging TypeScript's type system to ensure correctness at compile-time. Currently stable at version 3.x (e.g., 3.21.1), `effect` maintains a regular release cadence with frequent patch and minor updates, reflecting active development and continuous improvement. It differentiates itself through its comprehensive ecosystem of modules (e.g., `Effect.Layer`, `Effect.Schema`, `Effect.Stream`) that integrate seamlessly, offering a complete solution for complex application logic, asynchronous operations, and resource management without runtime exceptions.","status":"active","version":"3.21.1","language":"javascript","source_language":"en","source_url":"https://github.com/Effect-TS/effect","tags":["javascript","typescript"],"install":[{"cmd":"npm install effect","lang":"bash","label":"npm"},{"cmd":"yarn add effect","lang":"bash","label":"yarn"},{"cmd":"pnpm add effect","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Effect is the core data type representing a computation. The library is primarily ESM-first, especially in modern versions.","wrong":"const { Effect } = require('effect')","symbol":"Effect","correct":"import { Effect } from 'effect'"},{"note":"Layer is used for dependency injection. In v3+, all core modules are exported from the single 'effect' package, consolidating imports.","wrong":"import { Layer } from '@effect/data/Layer'","symbol":"Layer","correct":"import { Layer } from 'effect'"},{"note":"The `pipe` function is fundamental for functional composition. While `fp-ts` also uses `pipe`, `effect`'s version is integrated within its ecosystem. `pipe` is also often available as a method on `Effect` and other data types.","wrong":"import { pipe } from '@fp-ts/core'","symbol":"pipe","correct":"import { pipe } from 'effect'"},{"note":"Effect.gen uses generator functions with `yield*` for an imperative, async/await-like coding style, not regular async/await.","wrong":"const program = Effect.gen(async function () { /* ... */ });","symbol":"Effect.gen","correct":"import { Effect } from 'effect'; const program = Effect.gen(function* () { /* ... */ });"}],"quickstart":{"code":"import { Effect, Console, pipe, Duration, Schedule } from 'effect';\n\ninterface User {\n  id: number;\n  name: string;\n  email: string;\n}\n\n// Define a custom error type for better type safety\nclass UserNotFoundError extends Effect.Error('UserNotFoundError')<{ userId: number }> {}\nclass DatabaseConnectionError extends Effect.Error('DatabaseConnectionError')<{ message: string }> {}\n\n// Simulate fetching a user from a database\nconst fetchUserFromDB = (userId: number): Effect.Effect<User, UserNotFoundError | DatabaseConnectionError, never> =>\n  Effect.sync(() => {\n    if (userId === 1) {\n      return { id: 1, name: 'Alice', email: 'alice@example.com' };\n    } else if (userId === 99) {\n      throw new Error('Failed to connect to DB'); // Simulate a defect\n    }\n    return Effect.fail(new UserNotFoundError({ userId }));\n  }).pipe(\n    Effect.catchAllDefect((error) =>\n      Effect.fail(new DatabaseConnectionError({ message: String(error) }))\n    )\n  );\n\nconst program = pipe(\n  fetchUserFromDB(1), // Try to fetch user with ID 1\n  Effect.tap((user) => Console.log(`Fetched user: ${user.name}`)),\n  Effect.flatMap(() => fetchUserFromDB(2)), // Try to fetch user with ID 2 (will fail)\n  Effect.tapError((error) =>\n    error._tag === 'UserNotFoundError'\n      ? Console.error(`Error: User with ID ${error.userId} not found.`)\n      : Console.error(`Critical Error: ${error.message}`)\n  ),\n  Effect.retry(Schedule.exponential(Duration.seconds(1), 3)), // Retry failed operations with exponential backoff\n  Effect.matchEffect({ // Handle both success and failure paths explicitly\n    onFailure: (error) => Console.error(`Final failure: ${error._tag}`),\n    onSuccess: (user) => Console.log(`Final success (should not happen for user 2, unless retries succeed): ${user.name}`),\n  })\n);\n\n// Run the Effect program\nEffect.runPromise(program).then(() => Console.log('Program finished.')).catch(console.error);\n","lang":"typescript","description":"This quickstart demonstrates creating and composing Effects, handling different types of errors with custom error classes, using `pipe` for composition, applying retry logic, and running the Effect to a Promise, including a simulated database defect."},"warnings":[{"fix":"Consult the official migration guide for the specific major version upgrade. For v3, update imports, service definitions, Effect.gen usage, and error types.","message":"Major versions (e.g., v2 to v3) introduce significant breaking changes, including module reorganizations, API renames (e.g., `Either` to `Result`), and changes to `Layer` and `Service` definitions.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Always ensure your Effect computation is eventually passed to a runner function, typically at the 'edge' of your application or within a specific execution context.","message":"Effects are 'cold' and lazy; they describe a computation but do not execute until explicitly 'run' using functions like `Effect.runPromise`, `Effect.runSync`, or `Effect.runFork`. Forgetting to run an effect means its encapsulated logic (e.g., logging, side effects) will never occur.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Familiarize yourself with Effect's dependency injection system (Services and Layers). Ensure all required dependencies are correctly provided to your Effect computations via `Effect.provide` or `Layer.provide`.","message":"Understanding the `Effect<A, E, R>` type parameters (Success, Error, Requirements) is crucial for type safety, especially 'R' (Requirements/Context). Incorrectly managing or providing dependencies (Services/Layers) can lead to compile-time type errors related to missing `R` or runtime failures if services are not provided.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Always use `yield*` when composing Effect values inside an `Effect.gen` block. `yield*` performs the unwrapping and error propagation within the Effect runtime.","message":"When using `Effect.gen`, it's critical to use `yield*` (yield-star) for yielding other Effect values, not `await`. Using `await` directly within `Effect.gen` will often lead to unexpected behavior or type errors because it does not properly unwrap the Effect context.","severity":"gotcha","affected_versions":">=2.0.0"},{"fix":"Update to `effect@3.21.1` or later to include the fix that ensures request `Deferred`s are completed even if the resolver dies with a defect.","message":"A recently fixed defect in `RequestResolver.makeBatched` could cause consumer fibers to hang indefinitely if the resolver died with a defect, because cleanup logic was not correctly handling failures.","severity":"gotcha","affected_versions":"<3.21.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you are calling `Effect.runPromise` on an actual `Effect` instance, e.g., `Effect.runPromise(myEffect)`. Also, check your imports for `Effect` to ensure it's not a `require` import if your project is ESM-first.","cause":"Attempting to call `runPromise` (or other runners) on a non-Effect value, or `Effect` itself, rather than an instance.","error":"TypeError: Effect.runPromise is not a function"},{"fix":"Explicitly specify the type parameters (`Effect<A, E, R>`) for effects, especially when defining functions that return them. Use `Effect.mapError`, `Effect.provide`, `Effect.catchAll` to adjust error and requirement types. When composing, ensure the types align or are handled.","cause":"Often arises from type inference issues, particularly when an effect is created without explicitly defining its R, E, or A parameters, or when composing effects with incompatible types.","error":"Type 'Effect<unknown, never, any>' is not assignable to type 'Effect<R, E, A>'"},{"fix":"Convert Promises to Effects using `Effect.promise`, `Effect.tryPromise`, or `Effect.async` (for more complex async operations). Do not `await` Effect values directly; use `yield*` within `Effect.gen`.","cause":"Mixing `async/await` (Promises) directly with `Effect` values without proper conversion.","error":"TS2345: Argument of type 'Promise<any>' is not assignable to parameter of type 'Effect<any, never, never>'"},{"fix":"Ensure methods are called correctly. If using the fluent `.pipe()` syntax, ensure it's on an Effect instance (`myEffect.pipe(Effect.map(...))`). If using the global `pipe` function, ensure it takes the value as its first argument (`pipe(myEffect, Effect.map(...))`).","cause":"Attempting to call a method like `Effect.succeed(value)()` or using `pipe` incorrectly, e.g., `Effect.pipe(...)` instead of `value.pipe(Effect.method(...))` or `pipe(value, Effect.method(...))`.","error":"TS2349: This expression is not callable."}],"ecosystem":"npm"}