# Table of Contents - [Introduction | Effect Documentation](#introduction-effect-documentation) - [Introduction | Effect Documentation](#introduction-effect-documentation) - [Introduction | Effect Documentation](#introduction-effect-documentation) - [Installation | Effect Documentation](#installation-effect-documentation) - [Why Effect? | Effect Documentation](#why-effect-effect-documentation) - [Create Effect App | Effect Documentation](#create-effect-app-effect-documentation) - [Importing Effect | Effect Documentation](#importing-effect-effect-documentation) - [The Effect Type | Effect Documentation](#the-effect-type-effect-documentation) - [Creating Effects | Effect Documentation](#creating-effects-effect-documentation) - [Running Effects | Effect Documentation](#running-effects-effect-documentation) - [Two Types of Errors | Effect Documentation](#two-types-of-errors-effect-documentation) - [Unexpected Errors | Effect Documentation](#unexpected-errors-effect-documentation) - [Using Generators | Effect Documentation](#using-generators-effect-documentation) --- # Introduction | Effect Documentation Introduction ============ Welcome to the Effect documentation! Effect is a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs. Some of the main Effect features include: | Feature | Description | | --- | --- | | **Concurrency** | Achieve highly-scalable, ultra low-latency applications through Effect’s fiber-based concurrency model. | | **Composability** | Construct highly maintainable, readable, and flexible software through the use of small, reusable building blocks. | | **Resource Safety** | Safely manage acquisition and release of resources, even when your program fails. | | **Type Safety** | Leverage the TypeScript type system to the fullest with Effect’s focus on type inference and type safety. | | **Error Handling** | Handle errors in a structured and reliable manner using Effect’s built-in error handling capabilities. | | **Asynchronicity** | Write code that looks the same, whether it is synchronous or asynchronous. | | **Observability** | With full tracing capabilities, you can easily debug and monitor the execution of your Effect program. | How to Use These Docs --------------------- [](#how-to-use-these-docs) The documentation is structured in a sequential manner, starting from the basics and progressing to more advanced topics. This allows you to follow along step-by-step as you build your Effect application. However, you have the flexibility to read the documentation in any order or jump directly to the pages that are relevant to your specific use case. To facilitate navigation within a page, you will find a table of contents on the right side of the screen. This allows you to easily jump between different sections of the page. ### Docs for LLMs [](#docs-for-llms) We support the [llms.txt](https://llmstxt.org/) convention for making documentation available to large language models and the applications that make use of them. Currently, we have the following root-level files: * [/llms.txt](https://effect.website/llms.txt) — a listing of the available files * [/llms-full.txt](https://effect.website/llms-full.txt) — complete documentation for Effect * [/llms-small.txt](https://effect.website/llms-small.txt) — compressed documentation for use with smaller context windows Join our Community ------------------ [](#join-our-community) If you have questions about anything related to Effect, you’re always welcome to ask our community on [Discord](https://discord.gg/effect-ts) . --- # Introduction | Effect Documentation Introduction ============ Welcome to the Effect documentation! Effect is a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs. Some of the main Effect features include: | Feature | Description | | --- | --- | | **Concurrency** | Achieve highly-scalable, ultra low-latency applications through Effect’s fiber-based concurrency model. | | **Composability** | Construct highly maintainable, readable, and flexible software through the use of small, reusable building blocks. | | **Resource Safety** | Safely manage acquisition and release of resources, even when your program fails. | | **Type Safety** | Leverage the TypeScript type system to the fullest with Effect’s focus on type inference and type safety. | | **Error Handling** | Handle errors in a structured and reliable manner using Effect’s built-in error handling capabilities. | | **Asynchronicity** | Write code that looks the same, whether it is synchronous or asynchronous. | | **Observability** | With full tracing capabilities, you can easily debug and monitor the execution of your Effect program. | How to Use These Docs --------------------- [](#how-to-use-these-docs) The documentation is structured in a sequential manner, starting from the basics and progressing to more advanced topics. This allows you to follow along step-by-step as you build your Effect application. However, you have the flexibility to read the documentation in any order or jump directly to the pages that are relevant to your specific use case. To facilitate navigation within a page, you will find a table of contents on the right side of the screen. This allows you to easily jump between different sections of the page. ### Docs for LLMs [](#docs-for-llms) We support the [llms.txt](https://llmstxt.org/) convention for making documentation available to large language models and the applications that make use of them. Currently, we have the following root-level files: * [/llms.txt](https://effect.website/llms.txt) — a listing of the available files * [/llms-full.txt](https://effect.website/llms-full.txt) — complete documentation for Effect * [/llms-small.txt](https://effect.website/llms-small.txt) — compressed documentation for use with smaller context windows Join our Community ------------------ [](#join-our-community) If you have questions about anything related to Effect, you’re always welcome to ask our community on [Discord](https://discord.gg/effect-ts) . --- # Introduction | Effect Documentation Introduction ============ Welcome to the Effect documentation! Effect is a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs. Some of the main Effect features include: | Feature | Description | | --- | --- | | **Concurrency** | Achieve highly-scalable, ultra low-latency applications through Effect’s fiber-based concurrency model. | | **Composability** | Construct highly maintainable, readable, and flexible software through the use of small, reusable building blocks. | | **Resource Safety** | Safely manage acquisition and release of resources, even when your program fails. | | **Type Safety** | Leverage the TypeScript type system to the fullest with Effect’s focus on type inference and type safety. | | **Error Handling** | Handle errors in a structured and reliable manner using Effect’s built-in error handling capabilities. | | **Asynchronicity** | Write code that looks the same, whether it is synchronous or asynchronous. | | **Observability** | With full tracing capabilities, you can easily debug and monitor the execution of your Effect program. | How to Use These Docs --------------------- [](#how-to-use-these-docs) The documentation is structured in a sequential manner, starting from the basics and progressing to more advanced topics. This allows you to follow along step-by-step as you build your Effect application. However, you have the flexibility to read the documentation in any order or jump directly to the pages that are relevant to your specific use case. To facilitate navigation within a page, you will find a table of contents on the right side of the screen. This allows you to easily jump between different sections of the page. ### Docs for LLMs [](#docs-for-llms) We support the [llms.txt](https://llmstxt.org/) convention for making documentation available to large language models and the applications that make use of them. Currently, we have the following root-level files: * [/llms.txt](https://effect.website/llms.txt) — a listing of the available files * [/llms-full.txt](https://effect.website/llms-full.txt) — complete documentation for Effect * [/llms-small.txt](https://effect.website/llms-small.txt) — compressed documentation for use with smaller context windows Join our Community ------------------ [](#join-our-community) If you have questions about anything related to Effect, you’re always welcome to ask our community on [Discord](https://discord.gg/effect-ts) . --- # Installation | Effect Documentation Installation ============ Requirements: * TypeScript 5.4 or newer. * Node.js, Deno, and Bun are supported. Automatic Installation ---------------------- [](#automatic-installation) To quickly set up a new Effect application, we recommend using `create-effect-app`, which will handle all configurations for you. To create a new project, run: * [npm](#tab-panel-44) * [pnpm](#tab-panel-45) * [Yarn](#tab-panel-46) * [Bun](#tab-panel-47) * [Deno](#tab-panel-48) npx create-effect-app@latest pnpm create effect-app@latest yarn create effect-app@latest bunx create-effect-app@latest deno init --npm effect-app@latest Once you complete the prompts, `create-effect-app` will create a folder with your project name and install all required dependencies. For more details on the CLI, see the [Create Effect App](/docs/getting-started/create-effect-app/) documentation. Manual Installation ------------------- [](#manual-installation) ### Node.js [](#nodejs) Follow these steps to create a new Effect project for [Node.js](https://nodejs.org/) : 1. Create a project directory and navigate into it: mkdir hello-effectcd hello-effect 2. Initialize a TypeScript project: * [npm](#tab-panel-49) * [pnpm](#tab-panel-50) * [Yarn](#tab-panel-51) npm init -ynpm install --save-dev typescript pnpm initpnpm add --save-dev typescript yarn init -yyarn add --dev typescript This creates a `package.json` file with an initial setup for your TypeScript project. 3. Initialize TypeScript: * [npm](#tab-panel-52) * [pnpm](#tab-panel-53) * [Yarn](#tab-panel-54) npm tsc --init pnpm tsc --init yarn tsc --init When running this command, it will generate a `tsconfig.json` file that contains configuration options for TypeScript. One of the most important options to consider is the `strict` flag. Make sure to open the `tsconfig.json` file and verify that the value of the `strict` option is set to `true`. { "compilerOptions": { "strict": true }} 4. Install the necessary package as dependency: * [npm](#tab-panel-55) * [pnpm](#tab-panel-56) * [Yarn](#tab-panel-57) npm install effect pnpm add effect yarn add effect This package will provide the foundational functionality for your Effect project. Let’s write and run a simple program to ensure that everything is set up correctly. In your terminal, execute the following commands: mkdir srctouch src/index.ts Open the `index.ts` file and add the following code: 1import { Effect, Console } from "effect"2 3const program = Console.log("Hello, World!")4 5Effect.runSync(program) Run the `index.ts` file. Here we are using [tsx](https://github.com/privatenumber/tsx) to run the `index.ts` file in the terminal: npx tsx src/index.ts You should see the message `"Hello, World!"` printed. This confirms that the program is working correctly. ### Deno [](#deno) Follow these steps to create a new Effect project for [Deno](https://deno.com/) : 1. Create a project directory and navigate into it: mkdir hello-effectcd hello-effect 2. Initialize Deno: deno init 3. Install the necessary package as dependency: deno add npm:effect This package will provide the foundational functionality for your Effect project. Let’s write and run a simple program to ensure that everything is set up correctly. Open the `main.ts` file and replace the content with the following code: 1import { Effect, Console } from "effect"2 3const program = Console.log("Hello, World!")4 5Effect.runSync(program) Run the `main.ts` file: deno run main.ts You should see the message `"Hello, World!"` printed. This confirms that the program is working correctly. ### Bun [](#bun) Follow these steps to create a new Effect project for [Bun](https://bun.sh/) : 1. Create a project directory and navigate into it: mkdir hello-effectcd hello-effect 2. Initialize Bun: bun init When running this command, it will generate a `tsconfig.json` file that contains configuration options for TypeScript. One of the most important options to consider is the `strict` flag. Make sure to open the `tsconfig.json` file and verify that the value of the `strict` option is set to `true`. { "compilerOptions": { "strict": true }} 3. Install the necessary package as dependency: bun add effect This package will provide the foundational functionality for your Effect project. Let’s write and run a simple program to ensure that everything is set up correctly. Open the `index.ts` file and replace the content with the following code: 1import { Effect, Console } from "effect"2 3const program = Console.log("Hello, World!")4 5Effect.runSync(program) Run the `index.ts` file: bun index.ts You should see the message `"Hello, World!"` printed. This confirms that the program is working correctly. ### Vite + React [](#vite--react) Follow these steps to create a new Effect project for [Vite](https://vitejs.dev/guide/) + [React](https://react.dev/) : 1. Scaffold your Vite project, open your terminal and run the following command: * [npm](#tab-panel-58) * [pnpm](#tab-panel-59) * [Yarn](#tab-panel-60) * [Bun](#tab-panel-61) * [Deno](#tab-panel-62) # npm 6.xnpm create vite@latest hello-effect --template react-ts# npm 7+, extra double-dash is needednpm create vite@latest hello-effect -- --template react-ts pnpm create vite@latest hello-effect -- --template react-ts yarn create vite@latest hello-effect -- --template react-ts bun create vite@latest hello-effect -- --template react-ts deno init --npm vite@latest hello-effect -- --template react-ts This command will create a new Vite project with React and TypeScript template. 2. Navigate into the newly created project directory and install the required packages: * [npm](#tab-panel-63) * [pnpm](#tab-panel-64) * [Yarn](#tab-panel-65) * [Bun](#tab-panel-66) * [Deno](#tab-panel-67) cd hello-effectnpm install cd hello-effectpnpm install cd hello-effectyarn install cd hello-effectbun install cd hello-effectdeno install Once the packages are installed, open the `tsconfig.json` file and ensure that the value of the `strict` option is set to true. { "compilerOptions": { "strict": true }} 3. Install the necessary package as dependency: * [npm](#tab-panel-68) * [pnpm](#tab-panel-69) * [Yarn](#tab-panel-70) * [Bun](#tab-panel-71) * [Deno](#tab-panel-72) npm install effect pnpm add effect yarn add effect bun add effect deno add effect This package will provide the foundational functionality for your Effect project. Now, let’s write and run a simple program to ensure that everything is set up correctly. Open the `src/App.tsx` file and replace its content with the following code: 1import { useState, useMemo, useCallback } from "react"2import reactLogo from "./assets/react.svg"3import viteLogo from "/vite.svg"4import "./App.css"5import { Effect } from "effect"6 7function App() {8 const [count, setCount] = useState(0)9 10 const task = useMemo(11 () => Effect.sync(() => setCount((current) => current + 1)),12 [setCount]13 )14 15 const increment = useCallback(() => Effect.runSync(task), [task])16 17 return (18 <>19
20 21 Vite logo22 23 24 React logo25 26
27

Vite + React

28
29 30

31 Edit src/App.tsx and save to test HMR32

33
34

35 Click on the Vite and React logos to learn more36

37 38 )39}40 41export default App After making these changes, start the development server by running the following command: * [npm](#tab-panel-73) * [pnpm](#tab-panel-74) * [Yarn](#tab-panel-75) * [Bun](#tab-panel-76) * [Deno](#tab-panel-77) npm run dev pnpm run dev yarn run dev bun run dev deno run dev Then, press **o** to open the application in your browser. When you click the button, you should see the counter increment. This confirms that the program is working correctly. --- # Why Effect? | Effect Documentation Why Effect? =========== Programming is challenging. When we build libraries and apps, we look to many tools to handle the complexity and make our day-to-day more manageable. Effect presents a new way of thinking about programming in TypeScript. Effect is an ecosystem of tools that help you build better applications and libraries. As a result, you will also learn more about the TypeScript language and how to use the type system to make your programs more reliable and easier to maintain. In “typical” TypeScript, without Effect, we write code that assumes that a function is either successful or throws an exception. For example: 1const const divide: (a: number, b: number) => numberdivide = (a: numbera: number, b: numberb: number): number => {2 if (b: numberb === 0) {3 throw new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero")4 }5 return a: numbera / b: numberb6} Based on the types, we have no idea that this function can throw an exception. We can only find out by reading the code. This may not seem like much of a problem when you only have one function in your codebase, but when you have hundreds or thousands, it really starts to add up. It’s easy to forget that a function can throw an exception, and it’s easy to forget to handle that exception. Often, we will do the “easiest” thing and just wrap the function in a `try/catch` block. This is a good first step to prevent your program from crashing, but it doesn’t make it any easier to manage or understand our complex application/library. We can do better. One of the most important tools we have in TypeScript is the compiler. It is the first line of defense against bugs, domain errors, and general complexity. The Effect Pattern ------------------ [](#the-effect-pattern) While Effect is a vast ecosystem of many different tools, if it had to be reduced down to just one idea, it would be the following: Effect’s major unique insight is that we can use the type system to track **errors** and **context**, not only **success** values as shown in the divide example above. Here’s the same divide function from above, but with the Effect pattern: 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const divide: (a: number, b: number) => Effect.Effectdivide = (4 a: numbera: number,5 b: numberb: number6): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>7 b: numberb === 08 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))9 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb) With this approach, the function no longer throws exceptions. Instead, errors are handled as values, which can be passed along like success values. The type signature also makes it clear: * What success value the function returns (`number`). * What error can occur (`Error`). * What additional context or dependencies are required (`never` indicates none). ┌─── Produces a value of type number │ ┌─── Fails with an Error │ │ ┌─── Requires no dependencies ▼ ▼ ▼Effect Additionally, tracking context allows you to provide additional information to your functions without having to pass in everything as an argument. For example, you can swap out implementations of live external services with mocks during your tests without changing any core business logic. Don’t Re-Invent the Wheel ------------------------- [](#dont-re-invent-the-wheel) Application code in TypeScript often solves the same problems over and over again. Interacting with external services, filesystems, databases, etc. are common problems for all application developers. Effect provides a rich ecosystem of libraries that provide standardized solutions to many of these problems. You can use these libraries to build your application, or you can use them to build your own libraries. Managing challenges like error handling, debugging, tracing, async/promises, retries, streaming, concurrency, caching, resource management, and a lot more are made manageable with Effect. You don’t have to re-invent the solutions to these problems, or install tons of dependencies. Effect, under one umbrella, solves many of the problems that you would usually install many different dependencies with different APIs to solve. Solving Practical Problems -------------------------- [](#solving-practical-problems) Effect is heavily inspired by great work done in other languages, like Scala and Haskell. However, it’s important to understand that Effect’s goal is to be a practical toolkit, and it goes to great lengths to solve real, everyday problems that developers face when building applications and libraries in TypeScript. Enjoy Building and Learning --------------------------- [](#enjoy-building-and-learning) Learning Effect is a lot of fun. Many developers in the Effect ecosystem are using Effect to solve real problems in their day-to-day work, and also experiment with cutting edge ideas for pushing TypeScript to be the most useful language it can be. You don’t have to use all aspects of Effect at once, and can start with the pieces of the ecosystem that make the most sense for the problems you are solving. Effect is a toolkit, and you can pick and choose the pieces that make the most sense for your use case. However, as more and more of your codebase is using Effect, you will probably find yourself wanting to utilize more of the ecosystem! Effect’s concepts may be new to you, and might not completely make sense at first. This is totally normal. Take your time with reading the docs and try to understand the core concepts - this will really pay off later on as you get into the more advanced tooling in the Effect ecosystem. The Effect community is always happy to help you learn and grow. Feel free to hop into our [Discord](https://discord.gg/effect-ts) or discuss on [GitHub](https://github.com/Effect-TS) ! We are open to feedback and contributions, and are always looking for ways to improve Effect. --- # Create Effect App | Effect Documentation Create Effect App ================= The `create-effect-app` CLI allow you to create a new Effect application using a default template or an [example](https://github.com/Effect-TS/examples) from a public Github repository. It is the easiest way to get started with Effect. CLI --- [](#cli) To begin, run the `create-effect-app` command in your terminal using your preferred package manager: * [npm](#tab-panel-34) * [pnpm](#tab-panel-35) * [Yarn](#tab-panel-36) * [Bun](#tab-panel-37) * [Deno](#tab-panel-38) npx create-effect-app@latest pnpm create effect-app@latest yarn create effect-app@latest bunx create-effect-app@latest deno init --npm effect-app@latest This command starts an interactive setup that guides you through the steps required to bootstrap your project: ![create-effect-app](/_astro/interactive.D5H1oFy6_ZvF98P.webp "Animated GIF demonstrating the interactive experience when create-effect-app is run in interactive mode") After making your selections, `create-effect-app` will generate your new Effect project and configure it based on your choices. **Example** For instance, to create a new Effect project in a directory named `"my-effect-app"` using the basic template with ESLint integration, you can run: npx create-effect-app --template basic --eslint my-effect-app Non-Interactive Usage --------------------- [](#non-interactive-usage) If you prefer, `create-effect-app` can also be used in a non-interactive mode: create-effect-app (-t, --template basic | cli | monorepo) [--changesets] [--flake] [--eslint] [--workflows] []create-effect-app (-e, --example http-server) [] Below is a breakdown of the available options to customize an Effect project template: | Option | Description | | --- | --- | | `--changesets` | Initializes your project with the Changesets package for managing version control. | | `--flake` | Initializes your project with a Nix flake for managing system dependencies. | | `--eslint` | Includes ESLint for code formatting and linting. | | `--workflows` | Sets up Effect’s recommended GitHub Action workflows for automation. | --- # Importing Effect | Effect Documentation Importing Effect ================ If you’re just getting started, you might feel overwhelmed by the variety of modules and functions that Effect offers. However, rest assured that you don’t need to worry about all of them right away. This page will provide a simple introduction on how to import modules and functions, and explain that installing the `effect` package is generally all you need to begin. Installing Effect ----------------- [](#installing-effect) If you haven’t already installed the `effect` package, you can do so by running the following command in your terminal: * [npm](#tab-panel-39) * [pnpm](#tab-panel-40) * [Yarn](#tab-panel-41) * [Bun](#tab-panel-42) * [Deno](#tab-panel-43) npm install effect pnpm add effect yarn add effect bun add effect deno add npm:effect By installing this package, you get access to the core functionality of Effect. For detailed installation instructions for platforms like Deno or Bun, refer to the [Installation](/docs/getting-started/installation/) guide, which provides step-by-step guidance. You can also start a new Effect app using [`create-effect-app`](/docs/getting-started/create-effect-app/) , which automatically sets up everything for you. Importing Modules and Functions ------------------------------- [](#importing-modules-and-functions) Once you have installed the `effect` package, you can start using its modules and functions in your projects. Importing modules and functions is straightforward and follows the standard JavaScript/TypeScript import syntax. To import a module or a function from the `effect` package, simply use the `import` statement at the top of your file. Here’s how you can import the `Effect` module: import { Effect } from "effect" Now, you have access to the Effect module, which is the heart of the Effect library. It provides various functions to create, compose, and manipulate effectful computations. Namespace imports ----------------- [](#namespace-imports) In addition to importing the `Effect` module with a named import, as shown previously: import { Effect } from "effect" You can also import it using a namespace import like this: import * as Effect from "effect/Effect" Both forms of import allow you to access the functionalities provided by the `Effect` module. However an important consideration is **tree shaking**, which refers to a process that eliminates unused code during the bundling of your application. Named imports may generate tree shaking issues when a bundler doesn’t support deep scope analysis. Here are some bundlers that support deep scope analysis and thus don’t have issues with named imports: * Rollup * Webpack 5+ Functions vs Methods -------------------- [](#functions-vs-methods) In the Effect ecosystem, libraries often expose functions rather than methods. This design choice is important for two key reasons: tree shakeability and extendibility. ### Tree Shakeability [](#tree-shakeability) Tree shakeability refers to the ability of a build system to eliminate unused code during the bundling process. Functions are tree shakeable, while methods are not. When functions are used in the Effect ecosystem, only the functions that are actually imported and used in your application will be included in the final bundled code. Unused functions are automatically removed, resulting in a smaller bundle size and improved performance. On the other hand, methods are attached to objects or prototypes, and they cannot be easily tree shaken. Even if you only use a subset of methods, all methods associated with an object or prototype will be included in the bundle, leading to unnecessary code bloat. ### Extendibility [](#extendibility) Another important advantage of using functions in the Effect ecosystem is the ease of extendibility. With methods, extending the functionality of an existing API often requires modifying the prototype of the object, which can be complex and error-prone. In contrast, with functions, extending the functionality is much simpler. You can define your own “extension methods” as plain old functions without the need to modify the prototypes of objects. This promotes cleaner and more modular code, and it also allows for better compatibility with other libraries and modules. Commonly Used Functions ----------------------- [](#commonly-used-functions) As you start your adventure with Effect, you don’t need to dive into every function in the `effect` package right away. Instead, focus on some commonly used functions that will provide a solid foundation for your journey into the world of Effect. In the upcoming guides, we will explore some of these essential functions, specifically those for creating and running `Effect`s and building pipelines. But before we dive into those, let’s start from the very heart of Effect: understanding the `Effect` type. This will lay the groundwork for your understanding of how Effect brings composability, type safety, and error handling into your applications. So, let’s take the first step and explore the fundamental concepts of the [The Effect Type](/docs/getting-started/the-effect-type/) . --- # The Effect Type | Effect Documentation The Effect Type =============== The `Effect` type is an **immutable** description of a workflow or operation that is **lazily** executed. This means that when you create an `Effect`, it doesn’t run immediately, but instead defines a program that can succeed, fail, or require some additional context to complete. Here is the general form of an `Effect`: ┌─── Represents the success type │ ┌─── Represents the error type │ │ ┌─── Represents required dependencies ▼ ▼ ▼Effect This type indicates that an effect: * Succeeds and returns a value of type `Success` * Fails with an error of type `Error` * May need certain contextual dependencies of type `Requirements` to execute Conceptually, you can think of `Effect` as an effectful version of the following function type: type Effect = ( context: Context) => Error | Success However, effects are not actually functions. They can model synchronous, asynchronous, concurrent, and resourceful computations. **Immutability**. `Effect` values are immutable, and every function in the Effect library produces a new `Effect` value. **Modeling Interactions**. These values do not perform any actions themselves, they simply model or describe effectful interactions. **Execution**. An `Effect` can be executed by the [Effect Runtime System](/docs/runtime/) , which interprets it into actual interactions with the external world. Ideally, this execution happens at a single entry point in your application, such as the main function where effectful operations are initiated. Type Parameters --------------- [](#type-parameters) The `Effect` type has three type parameters with the following meanings: | Parameter | Description | | --- | --- | | **Success** | Represents the type of value that an effect can succeed with when executed. If this type parameter is `void`, it means the effect produces no useful information, while if it is `never`, it means the effect runs forever (or until failure). | | **Error** | Represents the expected errors that can occur when executing an effect. If this type parameter is `never`, it means the effect cannot fail, because there are no values of type `never`. | | **Requirements** | Represents the contextual data required by the effect to be executed. This data is stored in a collection named `Context`. If this type parameter is `never`, it means the effect has no requirements and the `Context` collection is empty. | Extracting Inferred Types ------------------------- [](#extracting-inferred-types) By using the utility types `Effect.Success`, `Effect.Error`, and `Effect.Context`, you can extract the corresponding types from an effect. **Example** (Extracting Success, Error, and Context Types) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import Context@since ― 2.0.0@since ― 2.0.0Context } from "effect"2 3class class SomeContextSomeContext extends import Context@since ― 2.0.0@since ― 2.0.0Context.const Tag: <"SomeContext">(id: "SomeContext") => () => Context.TagClass@example import * as assert from "node:assert"import { Context, Layer } from "effect" class MyTag extends Context.Tag("MyTag")< MyTag, { readonly myNum: number }>() { static Live = Layer.succeed(this, { myNum: 108 })}@since ― 2.0.0Tag("SomeContext")() {}4 5// Assume we have an effect that succeeds with a number,6// fails with an Error, and requires SomeContext7declare const const program: Effect.Effectprogram: import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect8 9// Extract the success type, which is number10type type A = numberA = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.namespace EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect.type Effect.Success> = [T] extends [Effect.Effect] ? _A : never@since ― 2.0.0Successprogram>11 12// Extract the error type, which is Error13type type E = ErrorE = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.namespace EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect.type Effect.Error> = [T] extends [Effect.Effect] ? _E : never@since ― 2.0.0Errorprogram>14 15// Extract the context type, which is SomeContext16type type R = SomeContextR = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.namespace EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect.type Effect.Context> = [T] extends [Effect.Effect] ? _R : never@since ― 2.0.0Contextprogram> --- # Creating Effects | Effect Documentation Creating Effects ================ Effect provides different ways to create effects, which are units of computation that encapsulate side effects. In this guide, we will cover some of the common methods that you can use to create effects. Why Not Throw Errors? --------------------- [](#why-not-throw-errors) In traditional programming, when an error occurs, it is often handled by throwing an exception: 1// Type signature doesn't show possible exceptions2const const divide: (a: number, b: number) => numberdivide = (a: numbera: number, b: numberb: number): number => {3 if (b: numberb === 0) {4 throw new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero")5 }6 return a: numbera / b: numberb7} However, throwing errors can be problematic. The type signatures of functions do not indicate that they can throw exceptions, making it difficult to reason about potential errors. To address this issue, Effect introduces dedicated constructors for creating effects that represent both success and failure: `Effect.succeed` and `Effect.fail`. These constructors allow you to explicitly handle success and failure cases while **leveraging the type system to track errors**. ### succeed [](#succeed) Creates an `Effect` that always succeeds with a given value. Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. **Example** (Creating a Successful Effect) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3// ┌─── Effect4// ▼5const const success: Effect.Effectsuccess = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(42) The type of `success` is `Effect`, which means: * It produces a value of type `number`. * It does not generate any errors (`never` indicates no errors). * It requires no additional data or dependencies (`never` indicates no requirements). ┌─── Produces a value of type number │ ┌─── Does not generate any errors │ │ ┌─── Requires no dependencies ▼ ▼ ▼Effect ### fail [](#fail) Creates an `Effect` that represents an error that can be recovered from. Use this function to explicitly signal an error in an `Effect`. The error will keep propagating unless it is handled. You can handle the error with functions like [Effect.catchAll](/docs/error-management/expected-errors/#catchall) or [Effect.catchTag](/docs/error-management/expected-errors/#catchtag) . **Example** (Creating a Failed Effect) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3// ┌─── Effect4// ▼5const const failure: Effect.Effectfailure = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(6 new var Error: ErrorConstructornew (message?: string) => ErrorError("Operation failed due to network error")7) The type of `failure` is `Effect`, which means: * It never produces a value (`never` indicates that no successful result will be produced). * It fails with an error, specifically an `Error`. * It requires no additional data or dependencies (`never` indicates no requirements). ┌─── Never produces a value │ ┌─── Fails with an Error │ │ ┌─── Requires no dependencies ▼ ▼ ▼Effect Although you can use `Error` objects with `Effect.fail`, you can also pass strings, numbers, or more complex objects depending on your error management strategy. Using “tagged” errors (objects with a `_tag` field) can help identify error types and works well with standard Effect functions, like [Effect.catchTag](/docs/error-management/expected-errors/#catchtag) . **Example** (Using Tagged Errors) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3class class HttpErrorHttpError {4 readonly HttpError._tag: "HttpError"_tag = "HttpError"5}6 7// ┌─── Effect8// ▼9const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: HttpError) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new constructor HttpError(): HttpErrorHttpError()) Error Tracking -------------- [](#error-tracking) With `Effect.succeed` and `Effect.fail`, you can explicitly handle success and failure cases and the type system will ensure that errors are tracked and accounted for. **Example** (Rewriting a Division Function) Here’s how you can rewrite the [`divide`](#why-not-throw-errors) function using Effect, making error handling explicit. 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const divide: (a: number, b: number) => Effect.Effectdivide = (a: numbera: number, b: numberb: number): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>4 b: numberb === 05 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))6 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb) In this example, the `divide` function indicates in its return type `Effect` that the operation can either succeed with a `number` or fail with an `Error`. ┌─── Produces a value of type number │ ┌─── Fails with an Error ▼ ▼Effect This clear type signature helps ensure that errors are handled properly and that anyone calling the function is aware of the possible outcomes. **Example** (Simulating a User Retrieval Operation) Let’s imagine another scenario where we use `Effect.succeed` and `Effect.fail` to model a simple user retrieval operation where the user data is hardcoded, which could be useful in testing scenarios or when mocking data: 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3// Define a User type4interface interface UserUser {5 readonly User.id: numberid: number6 readonly User.name: stringname: string7}8 9// A mocked function to simulate fetching a user from a database10const const getUser: (userId: number) => Effect.EffectgetUser = (userId: numberuserId: number): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect => {11 // Normally, you would access a database or API here, but we'll mock it12 const const userDatabase: RecorduserDatabase: type Record = { [P in K]: T; }Construct a type with a set of properties K of type TRecord = {13 1: { User.id: numberid: 1, User.name: stringname: "John Doe" },14 2: { User.id: numberid: 2, User.name: stringname: "Jane Smith" }15 }16 17 // Check if the user exists in our "database" and return appropriately18 const const user: Useruser = const userDatabase: RecorduserDatabase[userId: numberuserId]19 if (const user: Useruser) {20 return import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: User) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(const user: Useruser)21 } else {22 return import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("User not found"))23 }24}25 26// When executed, this will successfully return the user with id 127const const exampleUserEffect: Effect.EffectexampleUserEffect = const getUser: (userId: number) => Effect.EffectgetUser(1) In this example, `exampleUserEffect`, which has the type `Effect`, will either produce a `User` object or an `Error`, depending on whether the user exists in the mocked database. For a deeper dive into managing errors in your applications, refer to the [Error Management Guide](/docs/error-management/expected-errors/) . Modeling Synchronous Effects ---------------------------- [](#modeling-synchronous-effects) In JavaScript, you can delay the execution of synchronous computations using “thunks”. Thunks are useful for delaying the computation of a value until it is needed. To model synchronous side effects, Effect provides the `Effect.sync` and `Effect.try` constructors, which accept a thunk. ### sync [](#sync) Creates an `Effect` that represents a synchronous side-effectful computation. Use `Effect.sync` when you are sure the operation will not fail. The provided function (`thunk`) must not throw errors; if it does, the error will be treated as a [“defect”](/docs/error-management/unexpected-errors/) . This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like [Effect.catchAllDefect](/docs/error-management/unexpected-errors/#catchalldefect) . This feature ensures that even unexpected failures in your application are not lost and can be handled appropriately. **Example** (Logging a Message) In the example below, `Effect.sync` is used to defer the side-effect of writing to the console. 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const log: (message: string) => Effect.Effectlog = (message: stringmessage: string) =>4 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const sync: (thunk: LazyArg) => Effect.EffectCreates an Effect that represents a synchronous side-effectful computation. Details The provided function (thunk) must not throw errors; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . When to Use Use this function when you are sure the operation will not fail. Example (Logging a Message) import { Effect } from "effect" const log = (message: string) => Effect.sync(() => { console.log(message) // side effect }) // ┌─── Effect// ▼const program = log("Hello, World!")@see ― try_try for a version that can handle failures.@since ― 2.0.0sync(() => {5 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(message: stringmessage) // side effect6 })7 8// ┌─── Effect9// ▼10const const program: Effect.Effectprogram = const log: (message: string) => Effect.Effectlog("Hello, World!") The side effect (logging to the console) encapsulated within `program` won’t occur until the effect is explicitly run (see the [Running Effects](/docs/getting-started/running-effects/) section for more details). This allows you to define side effects at one point in your code and control when they are activated, improving manageability and predictability of side effects in larger applications. ### try [](#try) Creates an `Effect` that represents a synchronous computation that might fail. In situations where you need to perform synchronous operations that might fail, such as parsing JSON, you can use the `Effect.try` constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors. **Example** (Safe JSON Parsing) Suppose you have a function that attempts to parse a JSON string. This operation can fail and throw an error if the input string is not properly formatted as JSON: 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const parse: (input: string) => Effect.Effectparse = (input: stringinput: string) =>4 // This might throw an error if input is not valid JSON5 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.try(thunk: LazyArg): Effect.Effect (+1 overload)export trytry(() => var JSON: JSONAn intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.JSON.JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): anyConverts a JavaScript Object Notation (JSON) string into an object.@param ― text A valid JSON string.@param ― reviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.parse(input: stringinput))6 7// ┌─── Effect8// ▼9const const program: Effect.Effectprogram = const parse: (input: string) => Effect.Effectparse("") In this example: * `parse` is a function that creates an effect encapsulating the JSON parsing operation. * If `JSON.parse(input)` throws an error due to invalid input, `Effect.try` catches this error and the effect represented by `program` will fail with an `UnknownException`. This ensures that errors are not silently ignored but are instead handled within the structured flow of effects. #### Customizing Error Handling [](#customizing-error-handling) You might want to transform the caught exception into a more specific error or perform additional operations when catching an error. `Effect.try` supports an overload that allows you to specify how caught exceptions should be transformed: **Example** (Custom Error Handling) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const parse: (input: string) => Effect.Effectparse = (input: stringinput: string) =>4 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.try(options: { readonly try: LazyArg; readonly catch: (error: unknown) => Error;}): Effect.Effect (+1 overload)export trytry({5 // JSON.parse may throw for bad input6 try: LazyArgtry: () => var JSON: JSONAn intrinsic object that provides functions to convert JavaScript values to and from the JavaScript Object Notation (JSON) format.JSON.JSON.parse(text: string, reviver?: (this: any, key: string, value: any) => any): anyConverts a JavaScript Object Notation (JSON) string into an object.@param ― text A valid JSON string.@param ― reviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is.parse(input: stringinput),7 // remap the error8 catch: (error: unknown) => Errorcatch: (unknown: unknownunknown) => new var Error: ErrorConstructornew (message?: string) => ErrorError(`something went wrong ${unknown: unknownunknown}`)9 })10 11// ┌─── Effect12// ▼13const const program: Effect.Effectprogram = const parse: (input: string) => Effect.Effectparse("") You can think of this as a similar pattern to the traditional try-catch block in JavaScript: try { return JSON.parse(input)} catch (unknown) { throw new Error(`something went wrong ${unknown}`)} Modeling Asynchronous Effects ----------------------------- [](#modeling-asynchronous-effects) In traditional programming, we often use `Promise`s to handle asynchronous computations. However, dealing with errors in promises can be problematic. By default, `Promise` only provides the type `Value` for the resolved value, which means errors are not reflected in the type system. This limits the expressiveness and makes it challenging to handle and track errors effectively. To overcome these limitations, Effect introduces dedicated constructors for creating effects that represent both success and failure in an asynchronous context: `Effect.promise` and `Effect.tryPromise`. These constructors allow you to explicitly handle success and failure cases while **leveraging the type system to track errors**. ### promise [](#promise) Creates an `Effect` that represents an asynchronous computation guaranteed to succeed. Use `Effect.promise` when you are sure the operation will not reject. The provided function (`thunk`) returns a `Promise` that should never reject; if it does, the error will be treated as a [“defect”](/docs/error-management/unexpected-errors/) . This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like [Effect.catchAllDefect](/docs/error-management/unexpected-errors/#catchalldefect) . This feature ensures that even unexpected failures in your application are not lost and can be handled appropriately. **Example** (Delayed Message) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const delay: (message: string) => Effect.Effectdelay = (message: stringmessage: string) =>4 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(5 () =>6 new var Promise: PromiseConstructornew (executor: (resolve: (value: string | PromiseLike) => void, reject: (reason?: any) => void) => void) => PromiseCreates a new Promise.@param ― executor A callback used to initialize the promise. This callback is passed two arguments: a resolve callback used to resolve the promise with a value or the result of another promise, and a reject callback used to reject the promise with a provided reason or error.Promise((resolve: (value: string | PromiseLike) => voidresolve) => {7 function setTimeout<[]>(callback: () => void, ms?: number): NodeJS.Timeout (+1 overload)Schedules execution of a one-time callback after delay milliseconds. The callback will likely not be invoked in precisely delay milliseconds. Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. The callback will be called as close as possible to the time specified. When delay is larger than 2147483647 or less than 1, the delay will be set to 1. Non-integer delays are truncated to an integer. If callback is not a function, a TypeError will be thrown. This method has a custom variant for promises that is available using timersPromises.setTimeout().@since ― v0.0.1@param ― callback The function to call when the timer elapses.@param ― delay The number of milliseconds to wait before calling the callback.@param ― args Optional arguments to pass when the callback is called.setTimeout(() => {8 resolve: (value: string | PromiseLike) => voidresolve(message: stringmessage)9 }, 2000)10 })11 )12 13// ┌─── Effect14// ▼15const const program: Effect.Effectprogram = const delay: (message: string) => Effect.Effectdelay("Async operation completed successfully!") The `program` value has the type `Effect` and can be interpreted as an effect that: * succeeds with a value of type `string` * does not produce any expected error (`never`) * does not require any context (`never`) ### tryPromise [](#trypromise) Creates an `Effect` that represents an asynchronous computation that might fail. Unlike `Effect.promise`, this constructor is suitable when the underlying `Promise` might reject. It provides a way to catch errors and handle them appropriately. By default if an error occurs, it will be caught and propagated to the error channel as an `UnknownException`. **Example** (Fetching a TODO Item) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const getTodo: (id: number) => Effect.EffectgetTodo = (id: numberid: number) =>4 // Will catch any errors and propagate them as UnknownException5 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const tryPromise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.Effect (+1 overload)Creates an Effect that represents an asynchronous computation that might fail. When to Use In situations where you need to perform asynchronous operations that might fail, such as fetching data from an API, you can use the tryPromise constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors. Error Handling There are two ways to handle errors with tryPromise: If you don't provide a catch function, the error is caught and the effect fails with an UnknownException. If you provide a catch function, the error is caught and the catch function maps it to an error of type E. Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. Example (Fetching a TODO Item) import { Effect } from "effect" const getTodo = (id: number) => // Will catch any errors and propagate them as UnknownException Effect.tryPromise(() => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`) ) // ┌─── Effect// ▼const program = getTodo(1) Example (Custom Error Handling) import { Effect } from "effect" const getTodo = (id: number) => Effect.tryPromise({ try: () => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`), // remap the error catch: (unknown) => new Error(`something went wrong ${unknown}`) }) // ┌─── Effect// ▼const program = getTodo(1)@see ― promise if the effectful computation is asynchronous and does not throw errors.@since ― 2.0.0tryPromise(() =>6 function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promisefetch(`https://jsonplaceholder.typicode.com/todos/${id: numberid}`)7 )8 9// ┌─── Effect10// ▼11const const program: Effect.Effectprogram = const getTodo: (id: number) => Effect.EffectgetTodo(1) The `program` value has the type `Effect` and can be interpreted as an effect that: * succeeds with a value of type `Response` * might produce an error (`UnknownException`) * does not require any context (`never`) #### Customizing Error Handling [](#customizing-error-handling-1) If you want more control over what gets propagated to the error channel, you can use an overload of `Effect.tryPromise` that takes a remapping function: **Example** (Custom Error Handling) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const getTodo: (id: number) => Effect.EffectgetTodo = (id: numberid: number) =>4 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const tryPromise: (options: { readonly try: (signal: AbortSignal) => PromiseLike; readonly catch: (error: unknown) => Error;}) => Effect.Effect<...> (+1 overload)Creates an Effect that represents an asynchronous computation that might fail. When to Use In situations where you need to perform asynchronous operations that might fail, such as fetching data from an API, you can use the tryPromise constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors. Error Handling There are two ways to handle errors with tryPromise: If you don't provide a catch function, the error is caught and the effect fails with an UnknownException. If you provide a catch function, the error is caught and the catch function maps it to an error of type E. Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. Example (Fetching a TODO Item) import { Effect } from "effect" const getTodo = (id: number) => // Will catch any errors and propagate them as UnknownException Effect.tryPromise(() => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`) ) // ┌─── Effect// ▼const program = getTodo(1) Example (Custom Error Handling) import { Effect } from "effect" const getTodo = (id: number) => Effect.tryPromise({ try: () => fetch(`https://jsonplaceholder.typicode.com/todos/${id}`), // remap the error catch: (unknown) => new Error(`something went wrong ${unknown}`) }) // ┌─── Effect// ▼const program = getTodo(1)@see ― promise if the effectful computation is asynchronous and does not throw errors.@since ― 2.0.0tryPromise({5 try: (signal: AbortSignal) => PromiseLiketry: () => function fetch(input: string | URL | globalThis.Request, init?: RequestInit): Promisefetch(`https://jsonplaceholder.typicode.com/todos/${id: numberid}`),6 // remap the error7 catch: (error: unknown) => Errorcatch: (unknown: unknownunknown) => new var Error: ErrorConstructornew (message?: string) => ErrorError(`something went wrong ${unknown: unknownunknown}`)8 })9 10// ┌─── Effect11// ▼12const const program: Effect.Effectprogram = const getTodo: (id: number) => Effect.EffectgetTodo(1) From a Callback --------------- [](#from-a-callback) Creates an `Effect` from a callback-based asynchronous function. Sometimes you have to work with APIs that don’t support `async/await` or `Promise` and instead use the callback style. To handle callback-based APIs, Effect provides the `Effect.async` constructor. **Example** (Wrapping a Callback API) Let’s wrap the `readFile` function from Node.js’s `fs` module into an Effect-based API (make sure `@types/node` is installed): 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2import * as module "node:fs"NodeFS from "node:fs"3 4const const readFile: (filename: string) => Effect.Effect, Error, never>readFile = (filename: stringfilename: string) =>5 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const async: , Error, never>(resume: (callback: (_: Effect.Effect, Error, never>) => void, signal: AbortSignal) => void | Effect.Effect<...>, blockingOn?: FiberId) => Effect.Effect<...>Creates an Effect from a callback-based asynchronous function. Details The resume function: Must be called exactly once. Any additional calls will be ignored. Can return an optional Effect that will be run if the Fiber executing this Effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted. Can receive an AbortSignal to handle interruption if needed. The FiberId of the fiber that may complete the async callback may also be specified using the blockingOn argument. This is called the "blocking fiber" because it suspends the fiber executing the async effect (i.e. semantically blocks the fiber from making progress). Specifying this fiber id in cases where it is known will improve diagnostics, but not affect the behavior of the returned effect. When to Use Use Effect.async when dealing with APIs that use callback-style instead of async/await or Promise. Example (Wrapping a Callback API) import { Effect } from "effect"import * as NodeFS from "node:fs" const readFile = (filename: string) => Effect.async((resume) => { NodeFS.readFile(filename, (error, data) => { if (error) { // Resume with a failed Effect if an error occurs resume(Effect.fail(error)) } else { // Resume with a succeeded Effect if successful resume(Effect.succeed(data)) } }) }) // ┌─── Effect// ▼const program = readFile("example.txt") Example (Handling Interruption with Cleanup) import { Effect, Fiber } from "effect"import * as NodeFS from "node:fs" // Simulates a long-running operation to write to a fileconst writeFileWithCleanup = (filename: string, data: string) => Effect.async((resume) => { const writeStream = NodeFS.createWriteStream(filename) // Start writing data to the file writeStream.write(data) // When the stream is finished, resume with success writeStream.on("finish", () => resume(Effect.void)) // In case of an error during writing, resume with failure writeStream.on("error", (err) => resume(Effect.fail(err))) // Handle interruption by returning a cleanup effect return Effect.sync(() => { console.log(`Cleaning up ${filename}`) NodeFS.unlinkSync(filename) }) }) const program = Effect.gen(function* () { const fiber = yield* Effect.fork( writeFileWithCleanup("example.txt", "Some long data...") ) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) // This will trigger the cleanup}) // Run the programEffect.runPromise(program)// Output:// Cleaning up example.txt Example (Handling Interruption with AbortSignal) import { Effect, Fiber } from "effect" // A task that supports interruption using AbortSignalconst interruptibleTask = Effect.async((resume, signal) => { // Handle interruption signal.addEventListener("abort", () => { console.log("Abort signal received") clearTimeout(timeoutId) }) // Simulate a long-running task const timeoutId = setTimeout(() => { console.log("Operation completed") resume(Effect.void) }, 2000)}) const program = Effect.gen(function* () { const fiber = yield* Effect.fork(interruptibleTask) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber)}) // Run the programEffect.runPromise(program)// Output:// Abort signal received@since ― 2.0.0asyncBuffer, interface ErrorError>((resume: (_: Effect.Effect, Error, never>) => voidresume) => {6 module "node:fs"NodeFS.function readFile(path: NodeFS.PathOrFileDescriptor, callback: (err: NodeJS.ErrnoException | null, data: Buffer) => void): void (+3 overloads)Asynchronously reads the entire contents of a file.@param ― path A path to a file. If a URL is provided, it must use the file: protocol. If a file descriptor is provided, the underlying file will not be closed automatically.readFile(filename: stringfilename, (error: NodeJS.ErrnoException | nullerror, data: Bufferdata) => {7 if (error: NodeJS.ErrnoException | nullerror) {8 // Resume with a failed Effect if an error occurs9 resume: (_: Effect.Effect, Error, never>) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: NodeJS.ErrnoException) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(error: NodeJS.ErrnoExceptionerror))10 } else {11 // Resume with a succeeded Effect if successful12 resume: (_: Effect.Effect, Error, never>) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: >(value: Buffer) => Effect.Effect, never, never>Creates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(data: Bufferdata))13 }14 })15 })16 17// ┌─── Effect18// ▼19const const program: Effect.Effect, Error, never>program = const readFile: (filename: string) => Effect.Effect, Error, never>readFile("example.txt") In the above example, we manually annotate the types when calling `Effect.async`: Effect.async((resume) => { // ...}) because TypeScript cannot infer the type parameters for a callback based on the return value inside the callback body. Annotating the types ensures that the values provided to `resume` match the expected types. The `resume` function inside `Effect.async` should be called exactly once. Calling it more than once will result in the extra calls being ignored. **Example** (Ignoring Subsequent `resume` Calls) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const async: (resume: (callback: (_: Effect.Effect) => void, signal: AbortSignal) => void | Effect.Effect, blockingOn?: FiberId) => Effect.Effect<...>Creates an Effect from a callback-based asynchronous function. Details The resume function: Must be called exactly once. Any additional calls will be ignored. Can return an optional Effect that will be run if the Fiber executing this Effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted. Can receive an AbortSignal to handle interruption if needed. The FiberId of the fiber that may complete the async callback may also be specified using the blockingOn argument. This is called the "blocking fiber" because it suspends the fiber executing the async effect (i.e. semantically blocks the fiber from making progress). Specifying this fiber id in cases where it is known will improve diagnostics, but not affect the behavior of the returned effect. When to Use Use Effect.async when dealing with APIs that use callback-style instead of async/await or Promise. Example (Wrapping a Callback API) import { Effect } from "effect"import * as NodeFS from "node:fs" const readFile = (filename: string) => Effect.async((resume) => { NodeFS.readFile(filename, (error, data) => { if (error) { // Resume with a failed Effect if an error occurs resume(Effect.fail(error)) } else { // Resume with a succeeded Effect if successful resume(Effect.succeed(data)) } }) }) // ┌─── Effect// ▼const program = readFile("example.txt") Example (Handling Interruption with Cleanup) import { Effect, Fiber } from "effect"import * as NodeFS from "node:fs" // Simulates a long-running operation to write to a fileconst writeFileWithCleanup = (filename: string, data: string) => Effect.async((resume) => { const writeStream = NodeFS.createWriteStream(filename) // Start writing data to the file writeStream.write(data) // When the stream is finished, resume with success writeStream.on("finish", () => resume(Effect.void)) // In case of an error during writing, resume with failure writeStream.on("error", (err) => resume(Effect.fail(err))) // Handle interruption by returning a cleanup effect return Effect.sync(() => { console.log(`Cleaning up ${filename}`) NodeFS.unlinkSync(filename) }) }) const program = Effect.gen(function* () { const fiber = yield* Effect.fork( writeFileWithCleanup("example.txt", "Some long data...") ) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) // This will trigger the cleanup}) // Run the programEffect.runPromise(program)// Output:// Cleaning up example.txt Example (Handling Interruption with AbortSignal) import { Effect, Fiber } from "effect" // A task that supports interruption using AbortSignalconst interruptibleTask = Effect.async((resume, signal) => { // Handle interruption signal.addEventListener("abort", () => { console.log("Abort signal received") clearTimeout(timeoutId) }) // Simulate a long-running task const timeoutId = setTimeout(() => { console.log("Operation completed") resume(Effect.void) }, 2000)}) const program = Effect.gen(function* () { const fiber = yield* Effect.fork(interruptibleTask) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber)}) // Run the programEffect.runPromise(program)// Output:// Abort signal received@since ― 2.0.0async((resume: (_: Effect.Effect) => voidresume) => {4 resume: (_: Effect.Effect) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(1))5 resume: (_: Effect.Effect) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(2)) // This line will be ignored6})7 8// Run the program9import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.then(onfulfilled?: ((value: number) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log) // Output: 1 ### Advanced Usage [](#advanced-usage) For more advanced use cases, `resume` can optionally return an `Effect` that will be executed if the fiber running this effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted. **Example** (Handling Interruption with Cleanup) In this example: * The `writeFileWithCleanup` function writes data to a file. * If the fiber running this effect is interrupted, the cleanup effect (which deletes the file) is executed. * This ensures that resources like open file handles are cleaned up properly when the operation is canceled. 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import FiberFiber } from "effect"2import * as module "node:fs"NodeFS from "node:fs"3 4// Simulates a long-running operation to write to a file5const const writeFileWithCleanup: (filename: string, data: string) => Effect.EffectwriteFileWithCleanup = (filename: stringfilename: string, data: stringdata: string) =>6 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const async: (resume: (callback: (_: Effect.Effect) => void, signal: AbortSignal) => void | Effect.Effect, blockingOn?: FiberId) => Effect.Effect<...>Creates an Effect from a callback-based asynchronous function. Details The resume function: Must be called exactly once. Any additional calls will be ignored. Can return an optional Effect that will be run if the Fiber executing this Effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted. Can receive an AbortSignal to handle interruption if needed. The FiberId of the fiber that may complete the async callback may also be specified using the blockingOn argument. This is called the "blocking fiber" because it suspends the fiber executing the async effect (i.e. semantically blocks the fiber from making progress). Specifying this fiber id in cases where it is known will improve diagnostics, but not affect the behavior of the returned effect. When to Use Use Effect.async when dealing with APIs that use callback-style instead of async/await or Promise. Example (Wrapping a Callback API) import { Effect } from "effect"import * as NodeFS from "node:fs" const readFile = (filename: string) => Effect.async((resume) => { NodeFS.readFile(filename, (error, data) => { if (error) { // Resume with a failed Effect if an error occurs resume(Effect.fail(error)) } else { // Resume with a succeeded Effect if successful resume(Effect.succeed(data)) } }) }) // ┌─── Effect// ▼const program = readFile("example.txt") Example (Handling Interruption with Cleanup) import { Effect, Fiber } from "effect"import * as NodeFS from "node:fs" // Simulates a long-running operation to write to a fileconst writeFileWithCleanup = (filename: string, data: string) => Effect.async((resume) => { const writeStream = NodeFS.createWriteStream(filename) // Start writing data to the file writeStream.write(data) // When the stream is finished, resume with success writeStream.on("finish", () => resume(Effect.void)) // In case of an error during writing, resume with failure writeStream.on("error", (err) => resume(Effect.fail(err))) // Handle interruption by returning a cleanup effect return Effect.sync(() => { console.log(`Cleaning up ${filename}`) NodeFS.unlinkSync(filename) }) }) const program = Effect.gen(function* () { const fiber = yield* Effect.fork( writeFileWithCleanup("example.txt", "Some long data...") ) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) // This will trigger the cleanup}) // Run the programEffect.runPromise(program)// Output:// Cleaning up example.txt Example (Handling Interruption with AbortSignal) import { Effect, Fiber } from "effect" // A task that supports interruption using AbortSignalconst interruptibleTask = Effect.async((resume, signal) => { // Handle interruption signal.addEventListener("abort", () => { console.log("Abort signal received") clearTimeout(timeoutId) }) // Simulate a long-running task const timeoutId = setTimeout(() => { console.log("Operation completed") resume(Effect.void) }, 2000)}) const program = Effect.gen(function* () { const fiber = yield* Effect.fork(interruptibleTask) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber)}) // Run the programEffect.runPromise(program)// Output:// Abort signal received@since ― 2.0.0async((resume: (_: Effect.Effect) => voidresume) => {7 const const writeStream: NodeFS.WriteStreamwriteStream = module "node:fs"NodeFS.function createWriteStream(path: NodeFS.PathLike, options?: BufferEncoding | WriteStreamOptions): NodeFS.WriteStreamoptions may also include a start option to allow writing data at some position past the beginning of the file, allowed values are in the [0, Number.MAX_SAFE_INTEGER] range. Modifying a file rather than replacing it may require the flags option to be set to r+ rather than the default w. The encoding can be any one of those accepted by Buffer. If autoClose is set to true (default behavior) on 'error' or 'finish' the file descriptor will be closed automatically. If autoClose is false, then the file descriptor won't be closed, even if there's an error. It is the application's responsibility to close it and make sure there's no file descriptor leak. By default, the stream will emit a 'close' event after it has been destroyed. Set the emitClose option to false to change this behavior. By providing the fs option it is possible to override the corresponding fs implementations for open, write, writev, and close. Overriding write() without writev() can reduce performance as some optimizations (_writev()) will be disabled. When providing the fs option, overrides for at least one of write and writev are required. If no fd option is supplied, an override for open is also required. If autoClose is true, an override for close is also required. Like fs.ReadStream, if fd is specified, fs.WriteStream will ignore the path argument and will use the specified file descriptor. This means that no 'open' event will be emitted. fd should be blocking; non-blocking fds should be passed to net.Socket. If options is a string, then it specifies the encoding.@since ― v0.1.31createWriteStream(filename: stringfilename)8 9 // Start writing data to the file10 const writeStream: NodeFS.WriteStreamwriteStream.WritableBase.write(chunk: any, callback?: (error: Error | null | undefined) => void): boolean (+1 overload)The writable.write() method writes some data to the stream, and calls the supplied callback once the data has been fully handled. If an error occurs, the callback will be called with the error as its first argument. The callback is called asynchronously and before 'error' is emitted. The return value is true if the internal buffer is less than the highWaterMark configured when the stream was created after admitting chunk. If false is returned, further attempts to write data to the stream should stop until the 'drain' event is emitted. While a stream is not draining, calls to write() will buffer chunk, and return false. Once all currently buffered chunks are drained (accepted for delivery by the operating system), the 'drain' event will be emitted. Once write() returns false, do not write more chunks until the 'drain' event is emitted. While calling write() on a stream that is not draining is allowed, Node.js will buffer all written chunks until maximum memory usage occurs, at which point it will abort unconditionally. Even before it aborts, high memory usage will cause poor garbage collector performance and high RSS (which is not typically released back to the system, even after the memory is no longer required). Since TCP sockets may never drain if the remote peer does not read the data, writing a socket that is not draining may lead to a remotely exploitable vulnerability. Writing data while the stream is not draining is particularly problematic for a Transform, because the Transform streams are paused by default until they are piped or a 'data' or 'readable' event handler is added. If the data to be written can be generated or fetched on demand, it is recommended to encapsulate the logic into a Readable and use pipe . However, if calling write() is preferred, it is possible to respect backpressure and avoid memory issues using the 'drain' event: function write(data, cb) { if (!stream.write(data)) { stream.once('drain', cb); } else { process.nextTick(cb); }} // Wait for cb to be called before doing any other write.write('hello', () => { console.log('Write completed, do more writes now.');}); A Writable stream in object mode will always ignore the encoding argument.@since ― v0.9.4@param ― chunk Optional data to write. For streams not operating in object mode, chunk must be a {string}, {Buffer}, {TypedArray} or {DataView}. For object mode streams, chunk may be any JavaScript value other than null.@param ― encoding The encoding, if chunk is a string.@param ― callback Callback for when this chunk of data is flushed.write(data: stringdata)11 12 // When the stream is finished, resume with success13 const writeStream: NodeFS.WriteStreamwriteStream.WriteStream.on(event: "finish", listener: () => void): NodeFS.WriteStream (+8 overloads)Adds the listener function to the end of the listeners array for the event named eventName. No checks are made to see if the listener has already been added. Multiple calls passing the same combination of eventName and listener will result in the listener being added, and called, multiple times. server.on('connection', (stream) => { console.log('someone connected!');}); Returns a reference to the EventEmitter, so that calls can be chained. By default, event listeners are invoked in the order they are added. The emitter.prependListener() method can be used as an alternative to add the event listener to the beginning of the listeners array. import { EventEmitter } from 'node:events';const myEE = new EventEmitter();myEE.on('foo', () => console.log('a'));myEE.prependListener('foo', () => console.log('b'));myEE.emit('foo');// Prints:// b// aon("finish", () => resume: (_: Effect.Effect) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const void: Effect.Effectexport voidRepresents an effect that does nothing and produces no value. When to Use Use this effect when you need to represent an effect that does nothing. This is useful in scenarios where you need to satisfy an effect-based interface or control program flow without performing any operations. For example, it can be used in situations where you want to return an effect from a function but do not need to compute or return any result.@since ― 2.0.0void))14 15 // In case of an error during writing, resume with failure16 const writeStream: NodeFS.WriteStreamwriteStream.WriteStream.on(event: "error", listener: (err: Error) => void): NodeFS.WriteStream (+8 overloads)Adds the listener function to the end of the listeners array for the event named eventName. No checks are made to see if the listener has already been added. Multiple calls passing the same combination of eventName and listener will result in the listener being added, and called, multiple times. server.on('connection', (stream) => { console.log('someone connected!');}); Returns a reference to the EventEmitter, so that calls can be chained. By default, event listeners are invoked in the order they are added. The emitter.prependListener() method can be used as an alternative to add the event listener to the beginning of the listeners array. import { EventEmitter } from 'node:events';const myEE = new EventEmitter();myEE.on('foo', () => console.log('a'));myEE.prependListener('foo', () => console.log('b'));myEE.emit('foo');// Prints:// b// aon("error", (err: Errorerr) => resume: (_: Effect.Effect) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(err: Errorerr)))17 18 // Handle interruption by returning a cleanup effect19 return import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const sync: (thunk: LazyArg) => Effect.EffectCreates an Effect that represents a synchronous side-effectful computation. Details The provided function (thunk) must not throw errors; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . When to Use Use this function when you are sure the operation will not fail. Example (Logging a Message) import { Effect } from "effect" const log = (message: string) => Effect.sync(() => { console.log(message) // side effect }) // ┌─── Effect// ▼const program = log("Hello, World!")@see ― try_try for a version that can handle failures.@since ― 2.0.0sync(() => {20 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(`Cleaning up ${filename: stringfilename}`)21 module "node:fs"NodeFS.function unlinkSync(path: NodeFS.PathLike): voidSynchronous unlink(2). Returns undefined.@since ― v0.1.21unlinkSync(filename: stringfilename)22 })23 })24 25const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, void>(f: (resume: Effect.Adapter) => Generator>, void, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {26 const const fiber: Fiber.RuntimeFiberfiber = yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fork: (self: Effect.Effect) => Effect.Effect, never, never>Creates a new fiber to run an effect concurrently. Details This function takes an effect and forks it into a separate fiber, allowing it to run concurrently without blocking the original effect. The new fiber starts execution immediately after being created, and the fiber object is returned immediately without waiting for the effect to begin. This is useful when you want to run tasks concurrently while continuing other tasks in the parent fiber. The forked fiber is attached to the parent fiber's scope. This means that when the parent fiber terminates, the child fiber will also be terminated automatically. This feature, known as "auto supervision," ensures that no fibers are left running unintentionally. If you prefer not to have this auto supervision behavior, you can use forkDaemon or forkIn . When to Use Use this function when you need to run an effect concurrently without blocking the current execution flow. For example, you might use it to launch background tasks or concurrent computations. However, working with fibers can be complex, so before using this function directly, you might want to explore higher-level functions like raceWith , zip , or others that can manage concurrency for you. Example import { Effect } from "effect" const fib = (n: number): Effect.Effect => n < 2 ? Effect.succeed(n) : Effect.zipWith(fib(n - 1), fib(n - 2), (a, b) => a + b) // ┌─── Effect, never, never>// ▼const fib10Fiber = Effect.fork(fib(10))@see ― forkWithErrorHandler for a version that allows you to handle errors.@since ― 2.0.0fork(27 const writeFileWithCleanup: (filename: string, data: string) => Effect.EffectwriteFileWithCleanup("example.txt", "Some long data...")28 )29 // Simulate interrupting the fiber after 1 second30 yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const sleep: (duration: DurationInput) => Effect.EffectSuspends the execution of an effect for a specified Duration. Details This function pauses the execution of an effect for a given duration. It is asynchronous, meaning that it does not block the fiber executing the effect. Instead, the fiber is suspended during the delay period and can resume once the specified time has passed. The duration can be specified using various formats supported by the Duration module, such as a string ("2 seconds") or numeric value representing milliseconds. Example import { Effect } from "effect" const program = Effect.gen(function*() { console.log("Starting task...") yield* Effect.sleep("3 seconds") // Waits for 3 seconds console.log("Task completed!")}) Effect.runFork(program)// Output:// Starting task...// Task completed!@since ― 2.0.0sleep("1 second")31 yield* import FiberFiber.const interrupt: (self: Fiber.Fiber) => Effect.Effect, never, never>Interrupts the fiber from whichever fiber is calling this method. If the fiber has already exited, the returned effect will resume immediately. Otherwise, the effect will resume when the fiber exits.@since ― 2.0.0interrupt(const fiber: Fiber.RuntimeFiberfiber) // This will trigger the cleanup32})33 34// Run the program35import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram)36/*37Output:38Cleaning up example.txt39*/ If the operation you’re wrapping supports interruption, the `resume` function can receive an `AbortSignal` to handle interruption requests directly. **Example** (Handling Interruption with `AbortSignal`) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import FiberFiber } from "effect"2 3// A task that supports interruption using AbortSignal4const const interruptibleTask: Effect.EffectinterruptibleTask = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const async: (resume: (callback: (_: Effect.Effect) => void, signal: AbortSignal) => void | Effect.Effect, blockingOn?: FiberId) => Effect.Effect<...>Creates an Effect from a callback-based asynchronous function. Details The resume function: Must be called exactly once. Any additional calls will be ignored. Can return an optional Effect that will be run if the Fiber executing this Effect is interrupted. This can be useful in scenarios where you need to handle resource cleanup if the operation is interrupted. Can receive an AbortSignal to handle interruption if needed. The FiberId of the fiber that may complete the async callback may also be specified using the blockingOn argument. This is called the "blocking fiber" because it suspends the fiber executing the async effect (i.e. semantically blocks the fiber from making progress). Specifying this fiber id in cases where it is known will improve diagnostics, but not affect the behavior of the returned effect. When to Use Use Effect.async when dealing with APIs that use callback-style instead of async/await or Promise. Example (Wrapping a Callback API) import { Effect } from "effect"import * as NodeFS from "node:fs" const readFile = (filename: string) => Effect.async((resume) => { NodeFS.readFile(filename, (error, data) => { if (error) { // Resume with a failed Effect if an error occurs resume(Effect.fail(error)) } else { // Resume with a succeeded Effect if successful resume(Effect.succeed(data)) } }) }) // ┌─── Effect// ▼const program = readFile("example.txt") Example (Handling Interruption with Cleanup) import { Effect, Fiber } from "effect"import * as NodeFS from "node:fs" // Simulates a long-running operation to write to a fileconst writeFileWithCleanup = (filename: string, data: string) => Effect.async((resume) => { const writeStream = NodeFS.createWriteStream(filename) // Start writing data to the file writeStream.write(data) // When the stream is finished, resume with success writeStream.on("finish", () => resume(Effect.void)) // In case of an error during writing, resume with failure writeStream.on("error", (err) => resume(Effect.fail(err))) // Handle interruption by returning a cleanup effect return Effect.sync(() => { console.log(`Cleaning up ${filename}`) NodeFS.unlinkSync(filename) }) }) const program = Effect.gen(function* () { const fiber = yield* Effect.fork( writeFileWithCleanup("example.txt", "Some long data...") ) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber) // This will trigger the cleanup}) // Run the programEffect.runPromise(program)// Output:// Cleaning up example.txt Example (Handling Interruption with AbortSignal) import { Effect, Fiber } from "effect" // A task that supports interruption using AbortSignalconst interruptibleTask = Effect.async((resume, signal) => { // Handle interruption signal.addEventListener("abort", () => { console.log("Abort signal received") clearTimeout(timeoutId) }) // Simulate a long-running task const timeoutId = setTimeout(() => { console.log("Operation completed") resume(Effect.void) }, 2000)}) const program = Effect.gen(function* () { const fiber = yield* Effect.fork(interruptibleTask) // Simulate interrupting the fiber after 1 second yield* Effect.sleep("1 second") yield* Fiber.interrupt(fiber)}) // Run the programEffect.runPromise(program)// Output:// Abort signal received@since ― 2.0.0async((resume: (_: Effect.Effect) => voidresume, signal: AbortSignalsignal) => {5 // Handle interruption6 signal: AbortSignalsignal.function addEventListener(type: string, listener: EventListener | EventListenerObject, options?: AddEventListenerOptions | boolean): voidAdds a new handler for the type event. Any given listener is added only once per type and per capture option value. If the once option is true, the listener is removed after the next time a type event is dispatched. The capture option is not used by Node.js in any functional way other than tracking registered event listeners per the EventTarget specification. Specifically, the capture option is used as part of the key when registering a listener. Any individual listener may be added once with capture = false, and once with capture = true.addEventListener("abort", () => {7 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log("Abort signal received")8 function clearTimeout(timeoutId: NodeJS.Timeout | string | number | undefined): voidCancels a Timeout object created by setTimeout().@since ― v0.0.1@param ― timeout A Timeout object as returned by setTimeout or the primitive of the Timeout object as a string or a number.clearTimeout(const timeoutId: NodeJS.TimeouttimeoutId)9 })10 11 // Simulate a long-running task12 const const timeoutId: NodeJS.TimeouttimeoutId = function setTimeout<[]>(callback: () => void, ms?: number): NodeJS.Timeout (+1 overload)Schedules execution of a one-time callback after delay milliseconds. The callback will likely not be invoked in precisely delay milliseconds. Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. The callback will be called as close as possible to the time specified. When delay is larger than 2147483647 or less than 1, the delay will be set to 1. Non-integer delays are truncated to an integer. If callback is not a function, a TypeError will be thrown. This method has a custom variant for promises that is available using timersPromises.setTimeout().@since ― v0.0.1@param ― callback The function to call when the timer elapses.@param ― delay The number of milliseconds to wait before calling the callback.@param ― args Optional arguments to pass when the callback is called.setTimeout(() => {13 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log("Operation completed")14 resume: (_: Effect.Effect) => voidresume(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const void: Effect.Effectexport voidRepresents an effect that does nothing and produces no value. When to Use Use this effect when you need to represent an effect that does nothing. This is useful in scenarios where you need to satisfy an effect-based interface or control program flow without performing any operations. For example, it can be used in situations where you want to return an effect from a function but do not need to compute or return any result.@since ― 2.0.0void)15 }, 2000)16})17 18const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, void>(f: (resume: Effect.Adapter) => Generator>, void, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {19 const const fiber: Fiber.RuntimeFiberfiber = yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fork: (self: Effect.Effect) => Effect.Effect, never, never>Creates a new fiber to run an effect concurrently. Details This function takes an effect and forks it into a separate fiber, allowing it to run concurrently without blocking the original effect. The new fiber starts execution immediately after being created, and the fiber object is returned immediately without waiting for the effect to begin. This is useful when you want to run tasks concurrently while continuing other tasks in the parent fiber. The forked fiber is attached to the parent fiber's scope. This means that when the parent fiber terminates, the child fiber will also be terminated automatically. This feature, known as "auto supervision," ensures that no fibers are left running unintentionally. If you prefer not to have this auto supervision behavior, you can use forkDaemon or forkIn . When to Use Use this function when you need to run an effect concurrently without blocking the current execution flow. For example, you might use it to launch background tasks or concurrent computations. However, working with fibers can be complex, so before using this function directly, you might want to explore higher-level functions like raceWith , zip , or others that can manage concurrency for you. Example import { Effect } from "effect" const fib = (n: number): Effect.Effect => n < 2 ? Effect.succeed(n) : Effect.zipWith(fib(n - 1), fib(n - 2), (a, b) => a + b) // ┌─── Effect, never, never>// ▼const fib10Fiber = Effect.fork(fib(10))@see ― forkWithErrorHandler for a version that allows you to handle errors.@since ― 2.0.0fork(const interruptibleTask: Effect.EffectinterruptibleTask)20 // Simulate interrupting the fiber after 1 second21 yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const sleep: (duration: DurationInput) => Effect.EffectSuspends the execution of an effect for a specified Duration. Details This function pauses the execution of an effect for a given duration. It is asynchronous, meaning that it does not block the fiber executing the effect. Instead, the fiber is suspended during the delay period and can resume once the specified time has passed. The duration can be specified using various formats supported by the Duration module, such as a string ("2 seconds") or numeric value representing milliseconds. Example import { Effect } from "effect" const program = Effect.gen(function*() { console.log("Starting task...") yield* Effect.sleep("3 seconds") // Waits for 3 seconds console.log("Task completed!")}) Effect.runFork(program)// Output:// Starting task...// Task completed!@since ― 2.0.0sleep("1 second")22 yield* import FiberFiber.const interrupt: (self: Fiber.Fiber) => Effect.Effect, never, never>Interrupts the fiber from whichever fiber is calling this method. If the fiber has already exited, the returned effect will resume immediately. Otherwise, the effect will resume when the fiber exits.@since ― 2.0.0interrupt(const fiber: Fiber.RuntimeFiberfiber)23})24 25// Run the program26import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram)27/*28Output:29Abort signal received30*/ Suspended Effects ----------------- [](#suspended-effects) `Effect.suspend` is used to delay the creation of an effect. It allows you to defer the evaluation of an effect until it is actually needed. The `Effect.suspend` function takes a thunk that represents the effect, and it wraps it in a suspended effect. **Syntax** const suspendedEffect = Effect.suspend(() => effect) Let’s explore some common scenarios where `Effect.suspend` proves useful. ### Lazy Evaluation [](#lazy-evaluation) When you want to defer the evaluation of an effect until it is required. This can be useful for optimizing the execution of effects, especially when they are not always needed or when their computation is expensive. Also, when effects with side effects or scoped captures are created, use `Effect.suspend` to re-execute on each invocation. **Example** (Lazy Evaluation with Side Effects) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3let let i: numberi = 04 5const const bad: Effect.Effectbad = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(let i: numberi++)6 7const const good: Effect.Effectgood = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const suspend: (effect: LazyArg>) => Effect.EffectDelays the creation of an Effect until it is actually needed. Details The Effect.suspend function takes a thunk that represents the effect and wraps it in a suspended effect. This means the effect will not be created until it is explicitly needed, which is helpful in various scenarios: Lazy Evaluation: Helps optimize performance by deferring computations, especially when the effect might not be needed, or when its computation is expensive. This also ensures that any side effects or scoped captures are re-executed on each invocation. Handling Circular Dependencies: Useful in managing circular dependencies, such as recursive functions that need to avoid eager evaluation to prevent stack overflow. Unifying Return Types: Can help TypeScript unify return types in situations where multiple branches of logic return different effects, simplifying type inference. When to Use Use this function when you need to defer the evaluation of an effect until it is required. This is particularly useful for optimizing expensive computations, managing circular dependencies, or resolving type inference issues. Example (Lazy Evaluation with Side Effects) import { Effect } from "effect" let i = 0 const bad = Effect.succeed(i++) const good = Effect.suspend(() => Effect.succeed(i++)) console.log(Effect.runSync(bad)) // Output: 0console.log(Effect.runSync(bad)) // Output: 0 console.log(Effect.runSync(good)) // Output: 1console.log(Effect.runSync(good)) // Output: 2 Example (Recursive Fibonacci) import { Effect } from "effect" const blowsUp = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith(blowsUp(n - 1), blowsUp(n - 2), (a, b) => a + b) console.log(Effect.runSync(blowsUp(32)))// crash: JavaScript heap out of memory const allGood = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith( Effect.suspend(() => allGood(n - 1)), Effect.suspend(() => allGood(n - 2)), (a, b) => a + b ) console.log(Effect.runSync(allGood(32)))// Output: 3524578 Example (Using Effect.suspend to Help TypeScript Infer Types) import { Effect } from "effect" // Without suspend, TypeScript may struggle with type inference.// Inferred type:// (a: number, b: number) =>// Effect | Effectconst withoutSuspend = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // Using suspend to unify return types.// Inferred type:// (a: number, b: number) => Effectconst withSuspend = (a: number, b: number) => Effect.suspend(() => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) )@since ― 2.0.0suspend(() => import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(let i: numberi++))8 9var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(const bad: Effect.Effectbad)) // Output: 010var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(const bad: Effect.Effectbad)) // Output: 011 12var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(const good: Effect.Effectgood)) // Output: 113var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(const good: Effect.Effectgood)) // Output: 2 In this example, `bad` is the result of calling `Effect.succeed(i++)` a single time, which increments the scoped variable but [returns its original value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Increment#postfix_increment) . `Effect.runSync(bad)` does not result in any new computation, because `Effect.succeed(i++)` has already been called. On the other hand, each time `Effect.runSync(good)` is called, the thunk passed to `Effect.suspend()` will be executed, outputting the scoped variable’s most recent value. ### Handling Circular Dependencies [](#handling-circular-dependencies) `Effect.suspend` is helpful in managing circular dependencies between effects, where one effect depends on another, and vice versa. For example it’s fairly common for `Effect.suspend` to be used in recursive functions to escape an eager call. **Example** (Recursive Fibonacci) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const blowsUp: (n: number) => Effect.EffectblowsUp = (n: numbern: number): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>4 n: numbern < 25 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(1)6 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const zipWith: (self: Effect.Effect, that: Effect.Effect, f: (a: number, b: number) => number, options?: { readonly concurrent?: boolean | undefined; readonly batching?: boolean | "inherit" | undefined; readonly concurrentFinalizers?: boolean | undefined;}) => Effect.Effect<...> (+1 overload)Combines two effects sequentially and applies a function to their results to produce a single value. Details This function runs two effects in sequence (or concurrently, if the { concurrent: true } option is provided) and combines their results using a provided function. Unlike zip , which returns a tuple of the results, this function processes the results with a custom function to produce a single output. Example (Combining Effects with a Custom Function) import { Effect } from "effect" const task1 = Effect.succeed(1).pipe( Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")))const task2 = Effect.succeed("hello").pipe( Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done"))) const task3 = Effect.zipWith( task1, task2, // Combines results into a single value (number, string) => number + string.length) Effect.runPromise(task3).then(console.log)// Output:// timestamp=... level=INFO fiber=#3 message="task1 done"// timestamp=... level=INFO fiber=#2 message="task2 done"// 6@since ― 2.0.0zipWith(const blowsUp: (n: number) => Effect.EffectblowsUp(n: numbern - 1), const blowsUp: (n: number) => Effect.EffectblowsUp(n: numbern - 2), (a: numbera, b: numberb) => a: numbera + b: numberb)7 8// console.log(Effect.runSync(blowsUp(32)))9// crash: JavaScript heap out of memory10 11const const allGood: (n: number) => Effect.EffectallGood = (n: numbern: number): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>12 n: numbern < 213 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(1)14 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const zipWith: (self: Effect.Effect, that: Effect.Effect, f: (a: number, b: number) => number, options?: { readonly concurrent?: boolean | undefined; readonly batching?: boolean | "inherit" | undefined; readonly concurrentFinalizers?: boolean | undefined;}) => Effect.Effect<...> (+1 overload)Combines two effects sequentially and applies a function to their results to produce a single value. Details This function runs two effects in sequence (or concurrently, if the { concurrent: true } option is provided) and combines their results using a provided function. Unlike zip , which returns a tuple of the results, this function processes the results with a custom function to produce a single output. Example (Combining Effects with a Custom Function) import { Effect } from "effect" const task1 = Effect.succeed(1).pipe( Effect.delay("200 millis"), Effect.tap(Effect.log("task1 done")))const task2 = Effect.succeed("hello").pipe( Effect.delay("100 millis"), Effect.tap(Effect.log("task2 done"))) const task3 = Effect.zipWith( task1, task2, // Combines results into a single value (number, string) => number + string.length) Effect.runPromise(task3).then(console.log)// Output:// timestamp=... level=INFO fiber=#3 message="task1 done"// timestamp=... level=INFO fiber=#2 message="task2 done"// 6@since ― 2.0.0zipWith(15 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const suspend: (effect: LazyArg>) => Effect.EffectDelays the creation of an Effect until it is actually needed. Details The Effect.suspend function takes a thunk that represents the effect and wraps it in a suspended effect. This means the effect will not be created until it is explicitly needed, which is helpful in various scenarios: Lazy Evaluation: Helps optimize performance by deferring computations, especially when the effect might not be needed, or when its computation is expensive. This also ensures that any side effects or scoped captures are re-executed on each invocation. Handling Circular Dependencies: Useful in managing circular dependencies, such as recursive functions that need to avoid eager evaluation to prevent stack overflow. Unifying Return Types: Can help TypeScript unify return types in situations where multiple branches of logic return different effects, simplifying type inference. When to Use Use this function when you need to defer the evaluation of an effect until it is required. This is particularly useful for optimizing expensive computations, managing circular dependencies, or resolving type inference issues. Example (Lazy Evaluation with Side Effects) import { Effect } from "effect" let i = 0 const bad = Effect.succeed(i++) const good = Effect.suspend(() => Effect.succeed(i++)) console.log(Effect.runSync(bad)) // Output: 0console.log(Effect.runSync(bad)) // Output: 0 console.log(Effect.runSync(good)) // Output: 1console.log(Effect.runSync(good)) // Output: 2 Example (Recursive Fibonacci) import { Effect } from "effect" const blowsUp = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith(blowsUp(n - 1), blowsUp(n - 2), (a, b) => a + b) console.log(Effect.runSync(blowsUp(32)))// crash: JavaScript heap out of memory const allGood = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith( Effect.suspend(() => allGood(n - 1)), Effect.suspend(() => allGood(n - 2)), (a, b) => a + b ) console.log(Effect.runSync(allGood(32)))// Output: 3524578 Example (Using Effect.suspend to Help TypeScript Infer Types) import { Effect } from "effect" // Without suspend, TypeScript may struggle with type inference.// Inferred type:// (a: number, b: number) =>// Effect | Effectconst withoutSuspend = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // Using suspend to unify return types.// Inferred type:// (a: number, b: number) => Effectconst withSuspend = (a: number, b: number) => Effect.suspend(() => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) )@since ― 2.0.0suspend(() => const allGood: (n: number) => Effect.EffectallGood(n: numbern - 1)),16 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const suspend: (effect: LazyArg>) => Effect.EffectDelays the creation of an Effect until it is actually needed. Details The Effect.suspend function takes a thunk that represents the effect and wraps it in a suspended effect. This means the effect will not be created until it is explicitly needed, which is helpful in various scenarios: Lazy Evaluation: Helps optimize performance by deferring computations, especially when the effect might not be needed, or when its computation is expensive. This also ensures that any side effects or scoped captures are re-executed on each invocation. Handling Circular Dependencies: Useful in managing circular dependencies, such as recursive functions that need to avoid eager evaluation to prevent stack overflow. Unifying Return Types: Can help TypeScript unify return types in situations where multiple branches of logic return different effects, simplifying type inference. When to Use Use this function when you need to defer the evaluation of an effect until it is required. This is particularly useful for optimizing expensive computations, managing circular dependencies, or resolving type inference issues. Example (Lazy Evaluation with Side Effects) import { Effect } from "effect" let i = 0 const bad = Effect.succeed(i++) const good = Effect.suspend(() => Effect.succeed(i++)) console.log(Effect.runSync(bad)) // Output: 0console.log(Effect.runSync(bad)) // Output: 0 console.log(Effect.runSync(good)) // Output: 1console.log(Effect.runSync(good)) // Output: 2 Example (Recursive Fibonacci) import { Effect } from "effect" const blowsUp = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith(blowsUp(n - 1), blowsUp(n - 2), (a, b) => a + b) console.log(Effect.runSync(blowsUp(32)))// crash: JavaScript heap out of memory const allGood = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith( Effect.suspend(() => allGood(n - 1)), Effect.suspend(() => allGood(n - 2)), (a, b) => a + b ) console.log(Effect.runSync(allGood(32)))// Output: 3524578 Example (Using Effect.suspend to Help TypeScript Infer Types) import { Effect } from "effect" // Without suspend, TypeScript may struggle with type inference.// Inferred type:// (a: number, b: number) =>// Effect | Effectconst withoutSuspend = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // Using suspend to unify return types.// Inferred type:// (a: number, b: number) => Effectconst withSuspend = (a: number, b: number) => Effect.suspend(() => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) )@since ― 2.0.0suspend(() => const allGood: (n: number) => Effect.EffectallGood(n: numbern - 2)),17 (a: numbera, b: numberb) => a: numbera + b: numberb18 )19 20var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(const allGood: (n: number) => Effect.EffectallGood(32))) // Output: 3524578 The `blowsUp` function creates a recursive Fibonacci sequence without deferring execution. Each call to `blowsUp` triggers further immediate recursive calls, rapidly increasing the JavaScript call stack size. Conversely, `allGood` avoids stack overflow by using `Effect.suspend` to defer the recursive calls. This mechanism doesn’t immediately execute the recursive effects but schedules them to be run later, thus keeping the call stack shallow and preventing a crash. ### Unifying Return Type [](#unifying-return-type) In situations where TypeScript struggles to unify the returned effect type, `Effect.suspend` can be employed to resolve this issue. **Example** (Using `Effect.suspend` to Help TypeScript Infer Types) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3/*4 Without suspend, TypeScript may struggle with type inference.5 6 Inferred type:7 (a: number, b: number) =>8 Effect | Effect9*/10const const withoutSuspend: (a: number, b: number) => Effect.Effect | Effect.EffectwithoutSuspend = (a: numbera: number, b: numberb: number) =>11 b: numberb === 012 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))13 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb)14 15/*16 Using suspend to unify return types.17 18 Inferred type:19 (a: number, b: number) => Effect20*/21const const withSuspend: (a: number, b: number) => Effect.EffectwithSuspend = (a: numbera: number, b: numberb: number) =>22 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const suspend: (effect: LazyArg>) => Effect.EffectDelays the creation of an Effect until it is actually needed. Details The Effect.suspend function takes a thunk that represents the effect and wraps it in a suspended effect. This means the effect will not be created until it is explicitly needed, which is helpful in various scenarios: Lazy Evaluation: Helps optimize performance by deferring computations, especially when the effect might not be needed, or when its computation is expensive. This also ensures that any side effects or scoped captures are re-executed on each invocation. Handling Circular Dependencies: Useful in managing circular dependencies, such as recursive functions that need to avoid eager evaluation to prevent stack overflow. Unifying Return Types: Can help TypeScript unify return types in situations where multiple branches of logic return different effects, simplifying type inference. When to Use Use this function when you need to defer the evaluation of an effect until it is required. This is particularly useful for optimizing expensive computations, managing circular dependencies, or resolving type inference issues. Example (Lazy Evaluation with Side Effects) import { Effect } from "effect" let i = 0 const bad = Effect.succeed(i++) const good = Effect.suspend(() => Effect.succeed(i++)) console.log(Effect.runSync(bad)) // Output: 0console.log(Effect.runSync(bad)) // Output: 0 console.log(Effect.runSync(good)) // Output: 1console.log(Effect.runSync(good)) // Output: 2 Example (Recursive Fibonacci) import { Effect } from "effect" const blowsUp = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith(blowsUp(n - 1), blowsUp(n - 2), (a, b) => a + b) console.log(Effect.runSync(blowsUp(32)))// crash: JavaScript heap out of memory const allGood = (n: number): Effect.Effect => n < 2 ? Effect.succeed(1) : Effect.zipWith( Effect.suspend(() => allGood(n - 1)), Effect.suspend(() => allGood(n - 2)), (a, b) => a + b ) console.log(Effect.runSync(allGood(32)))// Output: 3524578 Example (Using Effect.suspend to Help TypeScript Infer Types) import { Effect } from "effect" // Without suspend, TypeScript may struggle with type inference.// Inferred type:// (a: number, b: number) =>// Effect | Effectconst withoutSuspend = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // Using suspend to unify return types.// Inferred type:// (a: number, b: number) => Effectconst withSuspend = (a: number, b: number) => Effect.suspend(() => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) )@since ― 2.0.0suspend(() =>23 b: numberb === 024 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))25 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb)26 ) Cheatsheet ---------- [](#cheatsheet) The table provides a summary of the available constructors, along with their input and output types, allowing you to choose the appropriate function based on your needs. | API | Given | Result | | --- | --- | --- | | `succeed` | `A` | `Effect` | | `fail` | `E` | `Effect` | | `sync` | `() => A` | `Effect` | | `try` | `() => A` | `Effect` | | `try` (overload) | `() => A`, `unknown => E` | `Effect` | | `promise` | `() => Promise` | `Effect` | | `tryPromise` | `() => Promise` | `Effect` | | `tryPromise` (overload) | `() => Promise`, `unknown => E` | `Effect` | | `async` | `(Effect => void) => void` | `Effect` | | `suspend` | `() => Effect` | `Effect` | For the complete list of constructors, visit the [Effect Constructors Documentation](https://effect-ts.github.io/effect/effect/Effect.ts.html#constructors) . --- # Running Effects | Effect Documentation Running Effects =============== To execute an effect, you can use one of the many `run` functions provided by the `Effect` module. runSync ------- [](#runsync) Executes an effect synchronously, running it immediately and returning the result. **Example** (Synchronous Logging) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const sync: (thunk: LazyArg) => Effect.EffectCreates an Effect that represents a synchronous side-effectful computation. Details The provided function (thunk) must not throw errors; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . When to Use Use this function when you are sure the operation will not fail. Example (Logging a Message) import { Effect } from "effect" const log = (message: string) => Effect.sync(() => { console.log(message) // side effect }) // ┌─── Effect// ▼const program = log("Hello, World!")@see ― try_try for a version that can handle failures.@since ― 2.0.0sync(() => {4 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log("Hello, World!")5 return 16})7 8const const result: numberresult = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(const program: Effect.Effectprogram)9// Output: Hello, World!10 11var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(const result: numberresult)12// Output: 1 Use `Effect.runSync` to run an effect that does not fail and does not include any asynchronous operations. If the effect fails or involves asynchronous work, it will throw an error, and execution will stop where the failure or async operation occurs. **Example** (Incorrect Usage with Failing or Async Effects) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3try {4 // Attempt to run an effect that fails5 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => neverExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail("my error"))6} catch (var e: unknowne) {7 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error(var e: unknowne)8}9/*10Output:11(FiberFailure) Error: my error12*/13 14try {15 // Attempt to run an effect that involves async work16 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSync: (effect: Effect.Effect) => numberExecutes an effect synchronously, running it immediately and returning the result. Details This function evaluates the provided effect synchronously, returning its result directly. It is ideal for effects that do not fail or include asynchronous operations. If the effect does fail or involves async tasks, it will throw an error. Execution stops at the point of failure or asynchronous operation, making it unsuitable for effects that require asynchronous handling. Important: Attempting to run effects that involve asynchronous operations or failures will result in exceptions being thrown, so use this function with care for purely synchronous and error-free effects. When to Use Use this function when: You are sure that the effect will not fail or involve asynchronous operations. You need a direct, synchronous result from the effect. You are working within a context where asynchronous effects are not allowed. Avoid using this function for effects that can fail or require asynchronous handling. For such cases, consider using runPromise or runSyncExit . Example (Synchronous Logging) import { Effect } from "effect" const program = Effect.sync(() => { console.log("Hello, World!") return 1}) const result = Effect.runSync(program)// Output: Hello, World! console.log(result)// Output: 1 Example (Incorrect Usage with Failing or Async Effects) import { Effect } from "effect" try { // Attempt to run an effect that fails Effect.runSync(Effect.fail("my error"))} catch (e) { console.error(e)}// Output:// (FiberFailure) Error: my error try { // Attempt to run an effect that involves async work Effect.runSync(Effect.promise(() => Promise.resolve(1)))} catch (e) { console.error(e)}// Output:// (FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work@see ― runSyncExit for a version that returns an Exit type instead of throwing an error.@since ― 2.0.0runSync(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(1)))17} catch (var e: unknowne) {18 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error(var e: unknowne)19}20/*21Output:22(FiberFailure) AsyncFiberException: Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work23*/ runSyncExit ----------- [](#runsyncexit) Runs an effect synchronously and returns the result as an [Exit](/docs/data-types/exit/) type, which represents the outcome (success or failure) of the effect. Use `Effect.runSyncExit` to find out whether an effect succeeded or failed, including any defects, without dealing with asynchronous operations. The `Exit` type represents the result of the effect: * If the effect succeeds, the result is wrapped in a `Success`. * If it fails, the failure information is provided as a `Failure` containing a [Cause](/docs/data-types/cause/) type. **Example** (Handling Results as Exit) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSyncExit: (effect: Effect.Effect) => ExitRuns an effect synchronously and returns the result as an Exit type. Details This function executes the provided effect synchronously and returns an Exit type that encapsulates the outcome of the effect: If the effect succeeds, the result is wrapped in a Success. If the effect fails, it returns a Failure containing a Cause that explains the failure. If the effect involves asynchronous operations, this function will return a Failure with a Die cause, indicating that it cannot resolve the effect synchronously. This makes the function suitable for use only with effects that are synchronous in nature. When to Use Use this function when: You want to handle both success and failure outcomes in a structured way using the Exit type. You are working with effects that are purely synchronous and do not involve asynchronous operations. You need to debug or inspect failures, including their causes, in a detailed manner. Avoid using this function for effects that involve asynchronous operations, as it will fail with a Die cause. Example (Handling Results as Exit) import { Effect } from "effect" console.log(Effect.runSyncExit(Effect.succeed(1)))// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } console.log(Effect.runSyncExit(Effect.fail("my error")))// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// } Example (Asynchronous Operation Resulting in Die) import { Effect } from "effect" console.log(Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))))// Output:// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// _tag: 'Die',// defect: [Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work] {// fiber: [FiberRuntime],// _tag: 'AsyncFiberException',// name: 'AsyncFiberException'// }// }// }@since ― 2.0.0runSyncExit(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(1)))4/*5Output:6{7 _id: "Exit",8 _tag: "Success",9 value: 110}11*/12 13var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSyncExit: (effect: Effect.Effect) => ExitRuns an effect synchronously and returns the result as an Exit type. Details This function executes the provided effect synchronously and returns an Exit type that encapsulates the outcome of the effect: If the effect succeeds, the result is wrapped in a Success. If the effect fails, it returns a Failure containing a Cause that explains the failure. If the effect involves asynchronous operations, this function will return a Failure with a Die cause, indicating that it cannot resolve the effect synchronously. This makes the function suitable for use only with effects that are synchronous in nature. When to Use Use this function when: You want to handle both success and failure outcomes in a structured way using the Exit type. You are working with effects that are purely synchronous and do not involve asynchronous operations. You need to debug or inspect failures, including their causes, in a detailed manner. Avoid using this function for effects that involve asynchronous operations, as it will fail with a Die cause. Example (Handling Results as Exit) import { Effect } from "effect" console.log(Effect.runSyncExit(Effect.succeed(1)))// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } console.log(Effect.runSyncExit(Effect.fail("my error")))// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// } Example (Asynchronous Operation Resulting in Die) import { Effect } from "effect" console.log(Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))))// Output:// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// _tag: 'Die',// defect: [Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work] {// fiber: [FiberRuntime],// _tag: 'AsyncFiberException',// name: 'AsyncFiberException'// }// }// }@since ― 2.0.0runSyncExit(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail("my error")))14/*15Output:16{17 _id: "Exit",18 _tag: "Failure",19 cause: {20 _id: "Cause",21 _tag: "Fail",22 failure: "my error"23 }24}25*/ If the effect contains asynchronous operations, `Effect.runSyncExit` will return an `Failure` with a `Die` cause, indicating that the effect cannot be resolved synchronously. **Example** (Asynchronous Operation Resulting in Die) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runSyncExit: (effect: Effect.Effect) => ExitRuns an effect synchronously and returns the result as an Exit type. Details This function executes the provided effect synchronously and returns an Exit type that encapsulates the outcome of the effect: If the effect succeeds, the result is wrapped in a Success. If the effect fails, it returns a Failure containing a Cause that explains the failure. If the effect involves asynchronous operations, this function will return a Failure with a Die cause, indicating that it cannot resolve the effect synchronously. This makes the function suitable for use only with effects that are synchronous in nature. When to Use Use this function when: You want to handle both success and failure outcomes in a structured way using the Exit type. You are working with effects that are purely synchronous and do not involve asynchronous operations. You need to debug or inspect failures, including their causes, in a detailed manner. Avoid using this function for effects that involve asynchronous operations, as it will fail with a Die cause. Example (Handling Results as Exit) import { Effect } from "effect" console.log(Effect.runSyncExit(Effect.succeed(1)))// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } console.log(Effect.runSyncExit(Effect.fail("my error")))// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// } Example (Asynchronous Operation Resulting in Die) import { Effect } from "effect" console.log(Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))))// Output:// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// _tag: 'Die',// defect: [Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work] {// fiber: [FiberRuntime],// _tag: 'AsyncFiberException',// name: 'AsyncFiberException'// }// }// }@since ― 2.0.0runSyncExit(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(1))))4/*5Output:6{7 _id: 'Exit',8 _tag: 'Failure',9 cause: {10 _id: 'Cause',11 _tag: 'Die',12 defect: [Fiber #0 cannot be resolved synchronously. This is caused by using runSync on an effect that performs async work] {13 fiber: [FiberRuntime],14 _tag: 'AsyncFiberException',15 name: 'AsyncFiberException'16 }17 }18}19*/ runPromise ---------- [](#runpromise) Executes an effect and returns the result as a `Promise`. Use `Effect.runPromise` when you need to execute an effect and work with the result using `Promise` syntax, typically for compatibility with other promise-based code. **Example** (Running a Successful Effect as a Promise) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(1)).Promise.then(onfulfilled?: ((value: number) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)4// Output: 1 If the effect succeeds, the promise will resolve with the result. If the effect fails, the promise will reject with an error. **Example** (Handling a Failing Effect as a Rejected Promise) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail("my error")).Promise.catch(onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): PromiseAttaches a callback for only the rejection of the Promise.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of the callback.catch(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)4/*5Output:6(FiberFailure) Error: my error7*/ runPromiseExit -------------- [](#runpromiseexit) Runs an effect and returns a `Promise` that resolves to an [Exit](/docs/data-types/exit/) , which represents the outcome (success or failure) of the effect. Use `Effect.runPromiseExit` when you need to determine if an effect succeeded or failed, including any defects, and you want to work with a `Promise`. The `Exit` type represents the result of the effect: * If the effect succeeds, the result is wrapped in a `Success`. * If it fails, the failure information is provided as a `Failure` containing a [Cause](/docs/data-types/cause/) type. **Example** (Handling Results as Exit) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromiseExit: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => Promise>Runs an effect and returns a Promise that resolves to an Exit, representing the outcome. Details This function executes an effect and resolves to an Exit object. The Exit type provides detailed information about the result of the effect: If the effect succeeds, the Exit will be of type Success and include the value produced by the effect. If the effect fails, the Exit will be of type Failure and contain a Cause object, detailing the failure. Using this function allows you to examine both successful results and failure cases in a unified way, while still leveraging Promise for handling the asynchronous behavior of the effect. When to Use Use this function when you need to understand the outcome of an effect, whether it succeeded or failed, and want to work with this result using Promise syntax. This is particularly useful when integrating with systems that rely on promises but need more detailed error handling than a simple rejection. Example (Handling Results as Exit) import { Effect } from "effect" // Execute a successful effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.succeed(1)).then(console.log)// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } // Execute a failing effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.fail("my error")).then(console.log)// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }@since ― 2.0.0runPromiseExit(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(1)).Promise>.then(onfulfilled?: ((value: Exit) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)4/*5Output:6{7 _id: "Exit",8 _tag: "Success",9 value: 110}11*/12 13import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromiseExit: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => Promise>Runs an effect and returns a Promise that resolves to an Exit, representing the outcome. Details This function executes an effect and resolves to an Exit object. The Exit type provides detailed information about the result of the effect: If the effect succeeds, the Exit will be of type Success and include the value produced by the effect. If the effect fails, the Exit will be of type Failure and contain a Cause object, detailing the failure. Using this function allows you to examine both successful results and failure cases in a unified way, while still leveraging Promise for handling the asynchronous behavior of the effect. When to Use Use this function when you need to understand the outcome of an effect, whether it succeeded or failed, and want to work with this result using Promise syntax. This is particularly useful when integrating with systems that rely on promises but need more detailed error handling than a simple rejection. Example (Handling Results as Exit) import { Effect } from "effect" // Execute a successful effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.succeed(1)).then(console.log)// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } // Execute a failing effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.fail("my error")).then(console.log)// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }@since ― 2.0.0runPromiseExit(import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail("my error")).Promise>.then(onfulfilled?: ((value: Exit) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)14/*15Output:16{17 _id: "Exit",18 _tag: "Failure",19 cause: {20 _id: "Cause",21 _tag: "Fail",22 failure: "my error"23 }24}25*/ runFork ------- [](#runfork) The foundational function for running effects, returning a “fiber” that can be observed or interrupted. `Effect.runFork` is used to run an effect in the background by creating a fiber. It is the base function for all other run functions. It starts a fiber that can be observed or interrupted. **Example** (Running an Effect in the Background) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import ConsoleConsole, import ScheduleSchedule, import FiberFiber } from "effect"2 3// ┌─── Effect4// ▼5const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const repeat: (self: Effect.Effect, schedule: Schedule.Schedule) => Effect.Effect (+3 overloads)Repeats an effect based on a specified schedule or until the first failure. Details This function executes an effect repeatedly according to the given schedule. Each repetition occurs after the initial execution of the effect, meaning that the schedule determines the number of additional repetitions. For example, using Schedule.once will result in the effect being executed twice (once initially and once as part of the repetition). If the effect succeeds, it is repeated according to the schedule. If it fails, the repetition stops immediately, and the failure is returned. The schedule can also specify delays between repetitions, making it useful for tasks like retrying operations with backoff, periodic execution, or performing a series of dependent actions. You can combine schedules for more advanced repetition logic, such as adding delays, limiting recursions, or dynamically adjusting based on the outcome of each execution. Example (Success Example) import { Effect, Schedule, Console } from "effect" const action = Console.log("success")const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")const program = Effect.repeat(action, policy) Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`)) Example (Failure Example) import { Effect, Schedule } from "effect" let count = 0 // Define an async effect that simulates an action with possible failuresconst action = Effect.async((resume) => { if (count > 1) { console.log("failure") resume(Effect.fail("Uh oh!")) } else { count++ console.log("success") resume(Effect.succeed("yay!")) }}) const policy = Schedule.addDelay(Schedule.recurs(2), () => "100 millis")const program = Effect.repeat(action, policy) Effect.runPromiseExit(program).then(console.log)@since ― 2.0.0repeat(6 import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("running..."),7 import ScheduleSchedule.const spaced: (duration: DurationInput) => Schedule.ScheduleReturns a schedule that recurs continuously, with each repetition spaced by the specified duration from the last run. Details This schedule ensures that executions occur at a fixed interval, maintaining a consistent delay between repetitions. The delay starts from the end of the last execution, not from the schedule start time.@see ― fixed If you need to run at a fixed interval from the start.@since ― 2.0.0spaced("200 millis")8)9 10// ┌─── RuntimeFiber11// ▼12const const fiber: Fiber.RuntimeFiberfiber = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runFork: (effect: Effect.Effect, options?: RunForkOptions) => Fiber.RuntimeFiberRuns an effect in the background, returning a fiber that can be observed or interrupted. Unless you specifically need a Promise or synchronous operation, runFork is a good default choice. Details This function is the foundational way to execute an effect in the background. It creates a "fiber," a lightweight, cooperative thread of execution that can be observed (to access its result), interrupted, or joined. Fibers are useful for concurrent programming and allow effects to run independently of the main program flow. Once the effect is running in a fiber, you can monitor its progress, cancel it if necessary, or retrieve its result when it completes. If the effect fails, the fiber will propagate the failure, which you can observe and handle. When to Use Use this function when you need to run an effect in the background, especially if the effect is long-running or performs periodic tasks. It's suitable for tasks that need to run independently but might still need observation or management, like logging, monitoring, or scheduled tasks. This function is ideal if you don't need the result immediately or if the effect is part of a larger concurrent workflow. Example (Running an Effect in the Background) import { Effect, Console, Schedule, Fiber } from "effect" // ┌─── Effect// ▼const program = Effect.repeat( Console.log("running..."), Schedule.spaced("200 millis")) // ┌─── RuntimeFiber// ▼const fiber = Effect.runFork(program) setTimeout(() => { Effect.runFork(Fiber.interrupt(fiber))}, 500)@since ― 2.0.0runFork(const program: Effect.Effectprogram)13 14function setTimeout<[]>(callback: () => void, ms?: number): NodeJS.Timeout (+1 overload)Schedules execution of a one-time callback after delay milliseconds. The callback will likely not be invoked in precisely delay milliseconds. Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. The callback will be called as close as possible to the time specified. When delay is larger than 2147483647 or less than 1, the delay will be set to 1. Non-integer delays are truncated to an integer. If callback is not a function, a TypeError will be thrown. This method has a custom variant for promises that is available using timersPromises.setTimeout().@since ― v0.0.1@param ― callback The function to call when the timer elapses.@param ― delay The number of milliseconds to wait before calling the callback.@param ― args Optional arguments to pass when the callback is called.setTimeout(() => {15 import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runFork: , never>(effect: Effect.Effect, never, never>, options?: RunForkOptions) => Fiber.RuntimeFiber<...>Runs an effect in the background, returning a fiber that can be observed or interrupted. Unless you specifically need a Promise or synchronous operation, runFork is a good default choice. Details This function is the foundational way to execute an effect in the background. It creates a "fiber," a lightweight, cooperative thread of execution that can be observed (to access its result), interrupted, or joined. Fibers are useful for concurrent programming and allow effects to run independently of the main program flow. Once the effect is running in a fiber, you can monitor its progress, cancel it if necessary, or retrieve its result when it completes. If the effect fails, the fiber will propagate the failure, which you can observe and handle. When to Use Use this function when you need to run an effect in the background, especially if the effect is long-running or performs periodic tasks. It's suitable for tasks that need to run independently but might still need observation or management, like logging, monitoring, or scheduled tasks. This function is ideal if you don't need the result immediately or if the effect is part of a larger concurrent workflow. Example (Running an Effect in the Background) import { Effect, Console, Schedule, Fiber } from "effect" // ┌─── Effect// ▼const program = Effect.repeat( Console.log("running..."), Schedule.spaced("200 millis")) // ┌─── RuntimeFiber// ▼const fiber = Effect.runFork(program) setTimeout(() => { Effect.runFork(Fiber.interrupt(fiber))}, 500)@since ― 2.0.0runFork(import FiberFiber.const interrupt: (self: Fiber.Fiber) => Effect.Effect, never, never>Interrupts the fiber from whichever fiber is calling this method. If the fiber has already exited, the returned effect will resume immediately. Otherwise, the effect will resume when the fiber exits.@since ― 2.0.0interrupt(const fiber: Fiber.RuntimeFiberfiber))16}, 500) In this example, the `program` continuously logs “running…” with each repetition spaced 200 milliseconds apart. You can learn more about repetitions and scheduling in our [Introduction to Scheduling](/docs/scheduling/introduction/) guide. To stop the execution of the program, we use `Fiber.interrupt` on the fiber returned by `Effect.runFork`. This allows you to control the execution flow and terminate it when necessary. For a deeper understanding of how fibers work and how to handle interruptions, check out our guides on [Fibers](/docs/concurrency/fibers/) and [Interruptions](/docs/concurrency/basic-concurrency/#interruptions) . Synchronous vs. Asynchronous Effects ------------------------------------ [](#synchronous-vs-asynchronous-effects) In the Effect library, there is no built-in way to determine in advance whether an effect will execute synchronously or asynchronously. While this idea was considered in earlier versions of Effect, it was ultimately not implemented for a few important reasons: 1. **Complexity:** Introducing this feature to track sync/async behavior in the type system would make Effect more complex to use and limit its composability. 2. **Safety Concerns:** We experimented with different approaches to track asynchronous Effects, but they all resulted in a worse developer experience without significantly improving safety. Even with fully synchronous types, we needed to support a `fromCallback` combinator to work with APIs using Continuation-Passing Style (CPS). However, at the type level, it’s impossible to guarantee that such a function is always called immediately and not deferred. ### Best Practices for Running Effects [](#best-practices-for-running-effects) In most cases, effects are run at the outermost parts of your application. Typically, an application built around Effect will involve a single call to the main effect. Here’s how you should approach effect execution: * Use `runPromise` or `runFork`: For most cases, asynchronous execution should be the default. These methods provide the best way to handle Effect-based workflows. * Use `runSync` only when necessary: Synchronous execution should be considered an edge case, used only in scenarios where asynchronous execution is not feasible. For example, when you are sure the effect is purely synchronous and need immediate results. Cheatsheet ---------- [](#cheatsheet) The table provides a summary of the available `run*` functions, along with their input and output types, allowing you to choose the appropriate function based on your needs. | API | Given | Result | | --- | --- | --- | | `runSync` | `Effect` | `A` | | `runSyncExit` | `Effect` | `Exit` | | `runPromise` | `Effect` | `Promise` | | `runPromiseExit` | `Effect` | `Promise>` | | `runFork` | `Effect` | `RuntimeFiber` | You can find the complete list of `run*` functions [here](https://effect-ts.github.io/effect/effect/Effect.ts.html#running-effects) . --- # Two Types of Errors | Effect Documentation Two Types of Errors =================== Just like any other program, Effect programs may fail for expected or unexpected reasons. The difference between a non-Effect program and an Effect program is in the detail provided to you when your program fails. Effect attempts to preserve as much information as possible about what caused your program to fail to produce a detailed, comprehensive, and human readable failure message. In an Effect program, there are two possible ways for a program to fail: * **Expected Errors**: These are errors that developers anticipate and expect as part of normal program execution. * **Unexpected Errors**: These are errors that occur unexpectedly and are not part of the intended program flow. Expected Errors --------------- [](#expected-errors) These errors, also referred to as _failures_, _typed errors_ or _recoverable errors_, are errors that developers anticipate as part of the normal program execution. They serve a similar purpose to checked exceptions and play a role in defining the program’s domain and control flow. Expected errors **are tracked** at the type level by the `Effect` data type in the “Error” channel: const program: Effect it is evident from the type that the program can fail with an error of type `HttpError`. Unexpected Errors ----------------- [](#unexpected-errors) Unexpected errors, also referred to as _defects_, _untyped errors_, or _unrecoverable errors_, are errors that developers do not anticipate occurring during normal program execution. Unlike expected errors, which are considered part of a program’s domain and control flow, unexpected errors resemble unchecked exceptions and lie outside the expected behavior of the program. Since these errors are not expected, Effect **does not track** them at the type level. However, the Effect runtime does keep track of these errors and provides several methods to aid in recovering from unexpected errors. --- # Unexpected Errors | Effect Documentation Unexpected Errors ================= There are situations where you may encounter unexpected errors, and you need to decide how to handle them. Effect provides functions to help you deal with such scenarios, allowing you to take appropriate actions when errors occur during the execution of your effects. Creating Unrecoverable Errors ----------------------------- [](#creating-unrecoverable-errors) In the same way it is possible to leverage combinators such as [Effect.fail](/docs/getting-started/creating-effects/#fail) to create values of type `Effect` the Effect library provides tools to create defects. Creating defects is a common necessity when dealing with errors from which it is not possible to recover from a business logic perspective, such as attempting to establish a connection that is refused after multiple retries. In those cases terminating the execution of the effect and moving into reporting, through an output such as stdout or some external monitoring service, might be the best solution. The following functions and combinators allow for termination of the effect and are often used to convert values of type `Effect` into values of type `Effect` allowing the programmer an escape hatch from having to handle and recover from errors for which there is no sensible way to recover. ### die [](#die) Creates an effect that terminates a fiber with a specified error. Use `Effect.die` when encountering unexpected conditions in your code that should not be handled as regular errors but instead represent unrecoverable defects. The `Effect.die` function is used to signal a defect, which represents a critical and unexpected error in the code. When invoked, it produces an effect that does not handle the error and instead terminates the fiber. The error channel of the resulting effect is of type `never`, indicating that it cannot recover from this failure. **Example** (Terminating on Division by Zero with a Specified Error) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const divide: (a: number, b: number) => Effect.Effectdivide = (a: numbera: number, b: numberb: number) =>4 b: numberb === 05 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const die: (defect: unknown) => Effect.EffectCreates an effect that terminates a fiber with a specified error. Details This function is used to signal a defect, which represents a critical and unexpected error in the code. When invoked, it produces an effect that does not handle the error and instead terminates the fiber. The error channel of the resulting effect is of type never, indicating that it cannot recover from this failure. When to Use Use this function when encountering unexpected conditions in your code that should not be handled as regular errors but instead represent unrecoverable defects. Example (Terminating on Division by Zero with a Specified Error) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.die(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // ┌─── Effect// ▼const program = divide(1, 0) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) Error: Cannot divide by zero// ...stack trace...@see ― dieSync for a variant that throws a specified error, evaluated lazily.@see ― dieMessage for a variant that throws a RuntimeException with a message.@since ― 2.0.0die(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))6 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb)7 8// ┌─── Effect9// ▼10const const program: Effect.Effectprogram = const divide: (a: number, b: number) => Effect.Effectdivide(1, 0)11 12import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.catch(onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): PromiseAttaches a callback for only the rejection of the Promise.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of the callback.catch(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)13/*14Output:15(FiberFailure) Error: Cannot divide by zero16 ...stack trace...17*/ ### dieMessage [](#diemessage) Creates an effect that terminates a fiber with a `RuntimeException` containing the specified message. Use `Effect.dieMessage` when you want to terminate a fiber due to an unrecoverable defect and include a clear explanation in the message. The `Effect.dieMessage` function is used to signal a defect, representing a critical and unexpected error in the code. When invoked, it produces an effect that terminates the fiber with a `RuntimeException` carrying the given message. The resulting effect has an error channel of type `never`, indicating it does not handle or recover from the error. **Example** (Terminating on Division by Zero with a Specified Message) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const divide: (a: number, b: number) => Effect.Effectdivide = (a: numbera: number, b: numberb: number) =>4 b: numberb === 05 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const dieMessage: (message: string) => Effect.EffectCreates an effect that terminates a fiber with a RuntimeException containing the specified message. Details This function is used to signal a defect, representing a critical and unexpected error in the code. When invoked, it produces an effect that terminates the fiber with a RuntimeException carrying the given message. The resulting effect has an error channel of type never, indicating it does not handle or recover from the error. When to Use Use this function when you want to terminate a fiber due to an unrecoverable defect and include a clear explanation in the message. Example (Terminating on Division by Zero with a Specified Message) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.dieMessage("Cannot divide by zero") : Effect.succeed(a / b) // ┌─── Effect// ▼const program = divide(1, 0) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) RuntimeException: Cannot divide by zero// ...stack trace...@see ― die for a variant that throws a specified error.@see ― dieSync for a variant that throws a specified error, evaluated lazily.@since ― 2.0.0dieMessage("Cannot divide by zero")6 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb)7 8// ┌─── Effect9// ▼10const const program: Effect.Effectprogram = const divide: (a: number, b: number) => Effect.Effectdivide(1, 0)11 12import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.catch(onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): PromiseAttaches a callback for only the rejection of the Promise.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of the callback.catch(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)13/*14Output:15(FiberFailure) RuntimeException: Cannot divide by zero16 ...stack trace...17*/ Converting Failures to Defects ------------------------------ [](#converting-failures-to-defects) ### orDie [](#ordie) Converts an effect’s failure into a fiber termination, removing the error from the effect’s type. Use `Effect.orDie` when failures should be treated as unrecoverable defects and no error handling is required. The `Effect.orDie` function is used when you encounter errors that you do not want to handle or recover from. It removes the error type from the effect and ensures that any failure will terminate the fiber. This is useful for propagating failures as defects, signaling that they should not be handled within the effect. **Example** (Propagating an Error as a Defect) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const divide: (a: number, b: number) => Effect.Effect | Effect.Effectdivide = (a: numbera: number, b: numberb: number) =>4 b: numberb === 05 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))6 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb)7 8// ┌─── Effect9// ▼10const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const orDie: (self: Effect.Effect) => Effect.EffectConverts an effect's failure into a fiber termination, removing the error from the effect's type. Details The orDie function is used when you encounter errors that you do not want to handle or recover from. It removes the error type from the effect and ensures that any failure will terminate the fiber. This is useful for propagating failures as defects, signaling that they should not be handled within the effect. *When to Use Use orDie when failures should be treated as unrecoverable defects and no error handling is required. Example (Propagating an Error as a Defect) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // ┌─── Effect// ▼const program = Effect.orDie(divide(1, 0)) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) Error: Cannot divide by zero// ...stack trace...@see ― orDieWith if you need to customize the error.@since ― 2.0.0orDie(const divide: (a: number, b: number) => Effect.Effect | Effect.Effectdivide(1, 0))11 12import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.catch(onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): PromiseAttaches a callback for only the rejection of the Promise.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of the callback.catch(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)13/*14Output:15(FiberFailure) Error: Cannot divide by zero16 ...stack trace...17*/ ### orDieWith [](#ordiewith) Converts an effect’s failure into a fiber termination with a custom error. Use `Effect.orDieWith` when failures should terminate the fiber as defects, and you want to customize the error for clarity or debugging purposes. The `Effect.orDieWith` function behaves like [Effect.orDie](#ordie) , but it allows you to provide a mapping function to transform the error before terminating the fiber. This is useful for cases where you want to include a more detailed or user-friendly error when the failure is propagated as a defect. **Example** (Customizing Defect) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const divide: (a: number, b: number) => Effect.Effect | Effect.Effectdivide = (a: numbera: number, b: numberb: number) =>4 b: numberb === 05 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Cannot divide by zero"))6 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(a: numbera / b: numberb)7 8// ┌─── Effect9// ▼10const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const orDieWith: (self: Effect.Effect, f: (error: Error) => unknown) => Effect.Effect (+1 overload)Converts an effect's failure into a fiber termination with a custom error. Details The orDieWith function behaves like orDie , but it allows you to provide a mapping function to transform the error before terminating the fiber. This is useful for cases where you want to include a more detailed or user-friendly error when the failure is propagated as a defect. When to Use Use orDieWith when failures should terminate the fiber as defects, and you want to customize the error for clarity or debugging purposes. Example (Customizing Defect) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.fail(new Error("Cannot divide by zero")) : Effect.succeed(a / b) // ┌─── Effect// ▼const program = Effect.orDieWith( divide(1, 0), (error) => new Error(`defect: ${error.message}`)) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) Error: defect: Cannot divide by zero// ...stack trace...@see ― orDie if you don't need to customize the error.@since ― 2.0.0orDieWith(11 const divide: (a: number, b: number) => Effect.Effect | Effect.Effectdivide(1, 0),12 (error: Errorerror) => new var Error: ErrorConstructornew (message?: string) => ErrorError(`defect: ${error: Errorerror.Error.message: stringmessage}`)13)14 15import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.catch(onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): PromiseAttaches a callback for only the rejection of the Promise.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of the callback.catch(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)16/*17Output:18(FiberFailure) Error: defect: Cannot divide by zero19 ...stack trace...20*/ Catching All Defects -------------------- [](#catching-all-defects) There is no sensible way to recover from defects. The functions we’re about to discuss should be used only at the boundary between Effect and an external system, to transmit information on a defect for diagnostic or explanatory purposes. ### exit [](#exit) The `Effect.exit` function transforms an `Effect` into an effect that encapsulates both potential failure and success within an [Exit](/docs/data-types/exit/) data type: Effect -> Effect, never, R> This means if you have an effect with the following type: Effect and you call `Effect.exit` on it, the type becomes: Effect, never, never> The resulting effect cannot fail because the potential failure is now represented within the `Exit`’s `Failure` type. The error type of the returned effect is specified as `never`, confirming that the effect is structured to not fail. By yielding an `Exit`, we gain the ability to “pattern match” on this type to handle both failure and success cases within the generator function. **Example** (Catching Defects with `Effect.exit`) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import CauseCause, import ConsoleConsole, import ExitExit } from "effect"2 3// Simulating a runtime error4const const task: Effect.Effecttask = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const dieMessage: (message: string) => Effect.EffectCreates an effect that terminates a fiber with a RuntimeException containing the specified message. Details This function is used to signal a defect, representing a critical and unexpected error in the code. When invoked, it produces an effect that terminates the fiber with a RuntimeException carrying the given message. The resulting effect has an error channel of type never, indicating it does not handle or recover from the error. When to Use Use this function when you want to terminate a fiber due to an unrecoverable defect and include a clear explanation in the message. Example (Terminating on Division by Zero with a Specified Message) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.dieMessage("Cannot divide by zero") : Effect.succeed(a / b) // ┌─── Effect// ▼const program = divide(1, 0) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) RuntimeException: Cannot divide by zero// ...stack trace...@see ― die for a variant that throws a specified error.@see ― dieSync for a variant that throws a specified error, evaluated lazily.@since ― 2.0.0dieMessage("Boom!")5 6const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, void>(f: (resume: Effect.Adapter) => Generator>, void, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {7 const const exit: Exit.Exitexit = yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const exit: (self: Effect.Effect) => Effect.Effect, never, never>Encapsulates both success and failure of an Effect using the Exit type. Details This function converts an effect into one that always succeeds, wrapping its outcome in the Exit type. The Exit type provides explicit handling of both success (Exit.Success) and failure (Exit.Failure) cases, including defects (unrecoverable errors). Unlike either or option , this function also encapsulates defects, which are typically unrecoverable and would otherwise terminate the effect. With the Exit type, defects are represented in Exit.Failure, allowing for detailed introspection and structured error handling. This makes the resulting effect robust and incapable of direct failure (its error type is never). It is particularly useful for workflows where all outcomes, including unexpected defects, must be managed and analyzed. Example import { Effect, Cause, Console, Exit } from "effect" // Simulating a runtime errorconst task = Effect.dieMessage("Boom!") const program = Effect.gen(function* () { const exit = yield* Effect.exit(task) if (Exit.isFailure(exit)) { const cause = exit.cause if ( Cause.isDieType(cause) && Cause.isRuntimeException(cause.defect) ) { yield* Console.log( `RuntimeException defect caught: ${cause.defect.message}` ) } else { yield* Console.log("Unknown failure caught.") } }}) // We get an Exit.Success because we caught all failuresEffect.runPromiseExit(program).then(console.log)// Output:// RuntimeException defect caught: Boom!// {// _id: "Exit",// _tag: "Success",// value: undefined// }@see ― option for a version that uses Option instead.@see ― either for a version that uses Either instead.@since ― 2.0.0exit(const task: Effect.Effecttask)8 if (import ExitExit.const isFailure: (self: Exit.Exit) => self is Exit.FailureReturns true if the specified Exit is a Failure, false otherwise.@since ― 2.0.0isFailure(const exit: Exit.Exitexit)) {9 const const cause: Cause.Causecause = const exit: Exit.Failureexit.Failure.cause: Cause.Causecause10 if (11 import CauseCause.const isDieType: (self: Cause.Cause) => self is Cause.DieChecks if a Cause is a Die type.@see ― die Create a new Die cause@since ― 2.0.0isDieType(const cause: Cause.Causecause) &&12 import CauseCause.const isRuntimeException: (u: unknown) => u is Cause.RuntimeExceptionChecks if a given unknown value is a RuntimeException.@since ― 2.0.0isRuntimeException(const cause: Cause.Diecause.Die.defect: unknowndefect)13 ) {14 yield* import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log(15 `RuntimeException defect caught: ${const cause: Cause.Diecause.Die.defect: Cause.RuntimeExceptiondefect.message: stringmessage}`16 )17 } else {18 yield* import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("Unknown failure caught.")19 }20 }21})22 23// We get an Exit.Success because we caught all failures24import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromiseExit: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => Promise>Runs an effect and returns a Promise that resolves to an Exit, representing the outcome. Details This function executes an effect and resolves to an Exit object. The Exit type provides detailed information about the result of the effect: If the effect succeeds, the Exit will be of type Success and include the value produced by the effect. If the effect fails, the Exit will be of type Failure and contain a Cause object, detailing the failure. Using this function allows you to examine both successful results and failure cases in a unified way, while still leveraging Promise for handling the asynchronous behavior of the effect. When to Use Use this function when you need to understand the outcome of an effect, whether it succeeded or failed, and want to work with this result using Promise syntax. This is particularly useful when integrating with systems that rely on promises but need more detailed error handling than a simple rejection. Example (Handling Results as Exit) import { Effect } from "effect" // Execute a successful effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.succeed(1)).then(console.log)// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } // Execute a failing effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.fail("my error")).then(console.log)// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }@since ― 2.0.0runPromiseExit(const program: Effect.Effectprogram).Promise>.then(onfulfilled?: ((value: Exit.Exit) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)25/*26Output:27RuntimeException defect caught: Boom!28{29 _id: "Exit",30 _tag: "Success",31 value: undefined32}33*/ ### catchAllDefect [](#catchalldefect) Recovers from all defects using a provided recovery function. `Effect.catchAllDefect` allows you to handle defects, which are unexpected errors that usually cause the program to terminate. This function lets you recover from these defects by providing a function that handles the error. However, it does not handle expected errors (like those from [Effect.fail](/docs/getting-started/creating-effects/#fail) ) or execution interruptions (like those from [Effect.interrupt](/docs/concurrency/basic-concurrency/#interrupt) ). **Example** (Handling All Defects) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import CauseCause, import ConsoleConsole } from "effect"2 3// Simulating a runtime error4const const task: Effect.Effecttask = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const dieMessage: (message: string) => Effect.EffectCreates an effect that terminates a fiber with a RuntimeException containing the specified message. Details This function is used to signal a defect, representing a critical and unexpected error in the code. When invoked, it produces an effect that terminates the fiber with a RuntimeException carrying the given message. The resulting effect has an error channel of type never, indicating it does not handle or recover from the error. When to Use Use this function when you want to terminate a fiber due to an unrecoverable defect and include a clear explanation in the message. Example (Terminating on Division by Zero with a Specified Message) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.dieMessage("Cannot divide by zero") : Effect.succeed(a / b) // ┌─── Effect// ▼const program = divide(1, 0) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) RuntimeException: Cannot divide by zero// ...stack trace...@see ― die for a variant that throws a specified error.@see ― dieSync for a variant that throws a specified error, evaluated lazily.@since ― 2.0.0dieMessage("Boom!")5 6const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const catchAllDefect: (self: Effect.Effect, f: (defect: unknown) => Effect.Effect) => Effect.Effect (+1 overload)Recovers from all defects using a provided recovery function. When to Use There is no sensible way to recover from defects. This method should be used only at the boundary between Effect and an external system, to transmit information on a defect for diagnostic or explanatory purposes. Details catchAllDefect allows you to handle defects, which are unexpected errors that usually cause the program to terminate. This function lets you recover from these defects by providing a function that handles the error. However, it does not handle expected errors (like those from fail ) or execution interruptions (like those from interrupt ). When to Recover from Defects Defects are unexpected errors that typically shouldn't be recovered from, as they often indicate serious issues. However, in some cases, such as dynamically loaded plugins, controlled recovery might be needed. Example (Handling All Defects) import { Effect, Cause, Console } from "effect" // Simulating a runtime errorconst task = Effect.dieMessage("Boom!") const program = Effect.catchAllDefect(task, (defect) => { if (Cause.isRuntimeException(defect)) { return Console.log( `RuntimeException defect caught: ${defect.message}` ) } return Console.log("Unknown defect caught.")}) // We get an Exit.Success because we caught all defectsEffect.runPromiseExit(program).then(console.log)// Output:// RuntimeException defect caught: Boom!// {// _id: "Exit",// _tag: "Success",// value: undefined// }@since ― 2.0.0catchAllDefect(const task: Effect.Effecttask, (defect: unknowndefect) => {7 if (import CauseCause.const isRuntimeException: (u: unknown) => u is Cause.RuntimeExceptionChecks if a given unknown value is a RuntimeException.@since ― 2.0.0isRuntimeException(defect: unknowndefect)) {8 return import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log(9 `RuntimeException defect caught: ${defect: Cause.RuntimeExceptiondefect.message: stringmessage}`10 )11 }12 return import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("Unknown defect caught.")13})14 15// We get an Exit.Success because we caught all defects16import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromiseExit: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => Promise>Runs an effect and returns a Promise that resolves to an Exit, representing the outcome. Details This function executes an effect and resolves to an Exit object. The Exit type provides detailed information about the result of the effect: If the effect succeeds, the Exit will be of type Success and include the value produced by the effect. If the effect fails, the Exit will be of type Failure and contain a Cause object, detailing the failure. Using this function allows you to examine both successful results and failure cases in a unified way, while still leveraging Promise for handling the asynchronous behavior of the effect. When to Use Use this function when you need to understand the outcome of an effect, whether it succeeded or failed, and want to work with this result using Promise syntax. This is particularly useful when integrating with systems that rely on promises but need more detailed error handling than a simple rejection. Example (Handling Results as Exit) import { Effect } from "effect" // Execute a successful effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.succeed(1)).then(console.log)// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } // Execute a failing effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.fail("my error")).then(console.log)// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }@since ― 2.0.0runPromiseExit(const program: Effect.Effectprogram).Promise>.then(onfulfilled?: ((value: Exit) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)17/*18Output:19RuntimeException defect caught: Boom!20{21 _id: "Exit",22 _tag: "Success",23 value: undefined24}25*/ Catching Some Defects --------------------- [](#catching-some-defects) ### catchSomeDefect [](#catchsomedefect) Recovers from specific defects using a provided partial function. `Effect.catchSomeDefect` allows you to handle specific defects, which are unexpected errors that can cause the program to stop. It uses a partial function to catch only certain defects and ignores others. However, it does not handle expected errors (like those from [Effect.fail](/docs/getting-started/creating-effects/#fail) ) or execution interruptions (like those from [Effect.interrupt](/docs/concurrency/basic-concurrency/#interrupt) ). The function provided to `Effect.catchSomeDefect` acts as a filter and a handler for defects: * It receives the defect as an input. * If the defect matches a specific condition (e.g., a certain error type), the function returns an `Option.some` containing the recovery logic. * If the defect does not match, the function returns `Option.none`, allowing the defect to propagate. **Example** (Handling Specific Defects) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import CauseCause, import Option@since ― 2.0.0@since ― 2.0.0Option, import ConsoleConsole } from "effect"2 3// Simulating a runtime error4const const task: Effect.Effecttask = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const dieMessage: (message: string) => Effect.EffectCreates an effect that terminates a fiber with a RuntimeException containing the specified message. Details This function is used to signal a defect, representing a critical and unexpected error in the code. When invoked, it produces an effect that terminates the fiber with a RuntimeException carrying the given message. The resulting effect has an error channel of type never, indicating it does not handle or recover from the error. When to Use Use this function when you want to terminate a fiber due to an unrecoverable defect and include a clear explanation in the message. Example (Terminating on Division by Zero with a Specified Message) import { Effect } from "effect" const divide = (a: number, b: number) => b === 0 ? Effect.dieMessage("Cannot divide by zero") : Effect.succeed(a / b) // ┌─── Effect// ▼const program = divide(1, 0) Effect.runPromise(program).catch(console.error)// Output:// (FiberFailure) RuntimeException: Cannot divide by zero// ...stack trace...@see ― die for a variant that throws a specified error.@see ― dieSync for a variant that throws a specified error, evaluated lazily.@since ― 2.0.0dieMessage("Boom!")5 6const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const catchSomeDefect: (self: Effect.Effect, pf: (defect: unknown) => Option.Option>) => Effect.Effect<...> (+1 overload)Recovers from specific defects using a provided partial function. Details catchSomeDefect allows you to handle specific defects, which are unexpected errors that can cause the program to stop. It uses a partial function to catch only certain defects and ignores others. The function does not handle expected errors (such as those caused by fail ) or interruptions in execution (like those caused by interrupt ). This function provides a way to handle certain types of defects while allowing others to propagate and cause failure in the program. Note: There is no sensible way to recover from defects. This method should be used only at the boundary between Effect and an external system, to transmit information on a defect for diagnostic or explanatory purposes. How the Partial Function Works The function provided to catchSomeDefect acts as a filter and a handler for defects: It receives the defect as an input. If the defect matches a specific condition (e.g., a certain error type), the function returns an Option.some containing the recovery logic. If the defect does not match, the function returns Option.none, allowing the defect to propagate. Example (Handling Specific Defects) import { Effect, Cause, Option, Console } from "effect" // Simulating a runtime errorconst task = Effect.dieMessage("Boom!") const program = Effect.catchSomeDefect(task, (defect) => { if (Cause.isIllegalArgumentException(defect)) { return Option.some( Console.log( `Caught an IllegalArgumentException defect: ${defect.message}` ) ) } return Option.none()}) // Since we are only catching IllegalArgumentException// we will get an Exit.Failure because we simulated a runtime error.Effect.runPromiseExit(program).then(console.log)// Output:// {// _id: 'Exit',// _tag: 'Failure',// cause: {// _id: 'Cause',// _tag: 'Die',// defect: { _tag: 'RuntimeException' }// }// }@since ― 2.0.0catchSomeDefect(const task: Effect.Effecttask, (defect: unknowndefect) => {7 if (import CauseCause.const isIllegalArgumentException: (u: unknown) => u is Cause.IllegalArgumentExceptionChecks if a given unknown value is an IllegalArgumentException.@since ― 2.0.0isIllegalArgumentException(defect: unknowndefect)) {8 return import Option@since ― 2.0.0@since ― 2.0.0Option.const some: >(value: Effect.Effect) => Option.Option>Wraps the given value into an Option to represent its presence. Example (Creating an Option with a Value) import { Option } from "effect" // An Option holding the number 1//// ┌─── Option// ▼const value = Option.some(1) console.log(value)// Output: { _id: 'Option', _tag: 'Some', value: 1 }@see ― none for the opposite operation.@since ― 2.0.0some(9 import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log(10 `Caught an IllegalArgumentException defect: ${defect: Cause.IllegalArgumentExceptiondefect.message: stringmessage}`11 )12 )13 }14 return import Option@since ― 2.0.0@since ― 2.0.0Option.const none: () => Option.OptionRepresents the absence of a value by creating an empty Option. Option.none returns an Option, which is a subtype of Option. This means you can use it in place of any Option regardless of the type A. Example (Creating an Option with No Value) import { Option } from "effect" // An Option holding no value//// ┌─── Option// ▼const noValue = Option.none() console.log(noValue)// Output: { _id: 'Option', _tag: 'None' }@see ― some for the opposite operation.@since ― 2.0.0none()15})16 17// Since we are only catching IllegalArgumentException18// we will get an Exit.Failure because we simulated a runtime error.19import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromiseExit: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => Promise>Runs an effect and returns a Promise that resolves to an Exit, representing the outcome. Details This function executes an effect and resolves to an Exit object. The Exit type provides detailed information about the result of the effect: If the effect succeeds, the Exit will be of type Success and include the value produced by the effect. If the effect fails, the Exit will be of type Failure and contain a Cause object, detailing the failure. Using this function allows you to examine both successful results and failure cases in a unified way, while still leveraging Promise for handling the asynchronous behavior of the effect. When to Use Use this function when you need to understand the outcome of an effect, whether it succeeded or failed, and want to work with this result using Promise syntax. This is particularly useful when integrating with systems that rely on promises but need more detailed error handling than a simple rejection. Example (Handling Results as Exit) import { Effect } from "effect" // Execute a successful effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.succeed(1)).then(console.log)// Output:// {// _id: "Exit",// _tag: "Success",// value: 1// } // Execute a failing effect and get the Exit result as a PromiseEffect.runPromiseExit(Effect.fail("my error")).then(console.log)// Output:// {// _id: "Exit",// _tag: "Failure",// cause: {// _id: "Cause",// _tag: "Fail",// failure: "my error"// }// }@since ― 2.0.0runPromiseExit(const program: Effect.Effectprogram).Promise>.then(onfulfilled?: ((value: Exit) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)20/*21Output:22{23 _id: 'Exit',24 _tag: 'Failure',25 cause: {26 _id: 'Cause',27 _tag: 'Die',28 defect: { _tag: 'RuntimeException' }29 }30}31*/ --- # Using Generators | Effect Documentation Using Generators ================ Effect offers a convenient syntax, similar to `async`/`await`, to write effectful code using [generators](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator) . Understanding Effect.gen ------------------------ [](#understanding-effectgen) The `Effect.gen` utility simplifies the task of writing effectful code by utilizing JavaScript’s generator functions. This method helps your code appear and behave more like traditional synchronous code, which enhances both readability and error management. **Example** (Performing Transactions with Discounts) Let’s explore a practical program that performs a series of data transformations commonly found in application logic: 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3// Function to add a small service charge to a transaction amount4const const addServiceCharge: (amount: number) => numberaddServiceCharge = (amount: numberamount: number) => amount: numberamount + 15 6// Function to apply a discount safely to a transaction amount7const const applyDiscount: (total: number, discountRate: number) => Effect.EffectapplyDiscount = (8 total: numbertotal: number,9 discountRate: numberdiscountRate: number10): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>11 discountRate: numberdiscountRate === 012 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Discount rate cannot be zero"))13 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(total: numbertotal - (total: numbertotal * discountRate: numberdiscountRate) / 100)14 15// Simulated asynchronous task to fetch a transaction amount from a16// database17const const fetchTransactionAmount: Effect.EffectfetchTransactionAmount = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(100))18 19// Simulated asynchronous task to fetch a discount rate from a20// configuration file21const const fetchDiscountRate: Effect.EffectfetchDiscountRate = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(5))22 23// Assembling the program using a generator function24const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, string>(f: (resume: Effect.Adapter) => Generator>, string, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {25 // Retrieve the transaction amount26 const const transactionAmount: numbertransactionAmount = yield* const fetchTransactionAmount: Effect.EffectfetchTransactionAmount27 28 // Retrieve the discount rate29 const const discountRate: numberdiscountRate = yield* const fetchDiscountRate: Effect.EffectfetchDiscountRate30 31 // Calculate discounted amount32 const const discountedAmount: numberdiscountedAmount = yield* const applyDiscount: (total: number, discountRate: number) => Effect.EffectapplyDiscount(33 const transactionAmount: numbertransactionAmount,34 const discountRate: numberdiscountRate35 )36 37 // Apply service charge38 const const finalAmount: numberfinalAmount = const addServiceCharge: (amount: number) => numberaddServiceCharge(const discountedAmount: numberdiscountedAmount)39 40 // Return the total amount after applying the charge41 return `Final amount to charge: ${const finalAmount: numberfinalAmount}`42})43 44// Execute the program and log the result45import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.then(onfulfilled?: ((value: string) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)46// Output: Final amount to charge: 96 Key steps to follow when using `Effect.gen`: * Wrap your logic in `Effect.gen` * Use `yield*` to handle effects * Return the final result Comparing Effect.gen with async/await ------------------------------------- [](#comparing-effectgen-with-asyncawait) If you are familiar with `async`/`await`, you may notice that the flow of writing code is similar. Let’s compare the two approaches: * [Using Effect.gen](#tab-panel-78) * [Using Async / Await](#tab-panel-79) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const addServiceCharge: (amount: number) => numberaddServiceCharge = (amount: numberamount: number) => amount: numberamount + 14 5const const applyDiscount: (total: number, discountRate: number) => Effect.EffectapplyDiscount = (6 total: numbertotal: number,7 discountRate: numberdiscountRate: number8): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>9 discountRate: numberdiscountRate === 010 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Discount rate cannot be zero"))11 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed(total: numbertotal - (total: numbertotal * discountRate: numberdiscountRate) / 100)12 13const const fetchTransactionAmount: Effect.EffectfetchTransactionAmount = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(100))14 15const const fetchDiscountRate: Effect.EffectfetchDiscountRate = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(5))16 17export const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, string>(f: (resume: Effect.Adapter) => Generator>, string, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {18 const const transactionAmount: numbertransactionAmount = yield* const fetchTransactionAmount: Effect.EffectfetchTransactionAmount19 const const discountRate: numberdiscountRate = yield* const fetchDiscountRate: Effect.EffectfetchDiscountRate20 const const discountedAmount: numberdiscountedAmount = yield* const applyDiscount: (total: number, discountRate: number) => Effect.EffectapplyDiscount(21 const transactionAmount: numbertransactionAmount,22 const discountRate: numberdiscountRate23 )24 const const finalAmount: numberfinalAmount = const addServiceCharge: (amount: number) => numberaddServiceCharge(const discountedAmount: numberdiscountedAmount)25 return `Final amount to charge: ${const finalAmount: numberfinalAmount}`26}) 1const const addServiceCharge: (amount: number) => numberaddServiceCharge = (amount: numberamount: number) => amount: numberamount + 12 3const const applyDiscount: (total: number, discountRate: number) => PromiseapplyDiscount = (4 total: numbertotal: number,5 discountRate: numberdiscountRate: number6): interface PromiseRepresents the completion of an asynchronous operationPromise =>7 discountRate: numberdiscountRate === 08 ? var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.reject(reason?: any): PromiseCreates a new rejected promise for the provided reason.@param ― reason The reason the promise was rejected.@returns ― A new rejected Promise.reject(new var Error: ErrorConstructornew (message?: string) => ErrorError("Discount rate cannot be zero"))9 : var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(total: numbertotal - (total: numbertotal * discountRate: numberdiscountRate) / 100)10 11const const fetchTransactionAmount: PromisefetchTransactionAmount = var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(100)12 13const const fetchDiscountRate: PromisefetchDiscountRate = var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(5)14 15export const const program: () => Promiseprogram = async function () {16 const const transactionAmount: numbertransactionAmount = await const fetchTransactionAmount: PromisefetchTransactionAmount17 const const discountRate: numberdiscountRate = await const fetchDiscountRate: PromisefetchDiscountRate18 const const discountedAmount: numberdiscountedAmount = await const applyDiscount: (total: number, discountRate: number) => PromiseapplyDiscount(19 const transactionAmount: numbertransactionAmount,20 const discountRate: numberdiscountRate21 )22 const const finalAmount: numberfinalAmount = const addServiceCharge: (amount: number) => numberaddServiceCharge(const discountedAmount: numberdiscountedAmount)23 return `Final amount to charge: ${const finalAmount: numberfinalAmount}`24} It’s important to note that although the code appears similar, the two programs are not identical. The purpose of comparing them side by side is just to highlight the resemblance in how they are written. Embracing Control Flow ---------------------- [](#embracing-control-flow) One significant advantage of using `Effect.gen` in conjunction with generators is its capability to employ standard control flow constructs within the generator function. These constructs include `if`/`else`, `for`, `while`, and other branching and looping mechanisms, enhancing your ability to express complex control flow logic in your code. **Example** (Using Control Flow) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const calculateTax: (amount: number, taxRate: number) => Effect.EffectcalculateTax = (4 amount: numberamount: number,5 taxRate: numbertaxRate: number6): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect =>7 taxRate: numbertaxRate > 08 ? import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const succeed: (value: number) => Effect.EffectCreates an Effect that always succeeds with a given value. When to Use Use this function when you need an effect that completes successfully with a specific value without any errors or external dependencies. Example (Creating a Successful Effect) import { Effect } from "effect" // Creating an effect that represents a successful scenario//// ┌─── Effect// ▼const success = Effect.succeed(42)@see ― fail to create an effect that represents a failure.@since ― 2.0.0succeed((amount: numberamount * taxRate: numbertaxRate) / 100)9 : import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: Error) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(new var Error: ErrorConstructornew (message?: string) => ErrorError("Invalid tax rate"))10 11const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, void>(f: (resume: Effect.Adapter) => Generator>, void, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {12 let let i: numberi = 113 14 while (true) {15 if (let i: numberi === 10) {16 break // Break the loop when counter reaches 1017 } else {18 if (let i: numberi % 2 === 0) {19 // Calculate tax for even numbers20 var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log(yield* const calculateTax: (amount: number, taxRate: number) => Effect.EffectcalculateTax(100, let i: numberi))21 }22 let i: numberi++23 continue24 }25 }26})27 28import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram)29/*30Output:31232433634835*/ How to Raise Errors ------------------- [](#how-to-raise-errors) The `Effect.gen` API lets you integrate error handling directly into your workflow by yielding failed effects. You can introduce errors with `Effect.fail`, as shown in the example below. **Example** (Introducing an Error into the Flow) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import ConsoleConsole } from "effect"2 3const const task1: Effect.Effecttask1 = import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("task1...")4const const task2: Effect.Effecttask2 = import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("task2...")5 6const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: > | YieldWrap>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {7 // Perform some tasks8 yield* const task1: Effect.Effecttask19 yield* const task2: Effect.Effecttask210 // Introduce an error11 yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail("Something went wrong!")12})13 14import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.then(onfulfilled?: ((value: void) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log, var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)15/*16Output:17task1...18task2...19(FiberFailure) Error: Something went wrong!20*/ The Role of Short-Circuiting ---------------------------- [](#the-role-of-short-circuiting) When working with `Effect.gen`, it is important to understand how it handles errors. This API will stop execution at the **first error** it encounters and return that error. How does this affect your code? If you have several operations in sequence, once any one of them fails, the remaining operations will not run, and the error will be returned. In simpler terms, if something fails at any point, the program will stop right there and deliver the error to you. **Example** (Halting Execution at the First Error) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect, import ConsoleConsole } from "effect"2 3const const task1: Effect.Effecttask1 = import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("task1...")4const const task2: Effect.Effecttask2 = import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("task2...")5const const failure: Effect.Effectfailure = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail("Something went wrong!")6const const task4: Effect.Effecttask4 = import ConsoleConsole.const log: (...args: ReadonlyArray) => Effect.Effect@since ― 2.0.0log("task4...")7 8const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: > | YieldWrap>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {9 yield* const task1: Effect.Effecttask110 yield* const task2: Effect.Effecttask211 // The program stops here due to the error12 yield* const failure: Effect.Effectfailure13 // The following lines never run14 yield* const task4: Effect.Effecttask415 return "some result"16})17 18import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(const program: Effect.Effectprogram).Promise.then(onfulfilled?: ((value: string) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => void | PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log, var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.globalThis.Console.error(message?: any, ...optionalParams: any[]): voidPrints to stderr with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const code = 5;console.error('error #%d', code);// Prints: error #5, to stderrconsole.error('error', code);// Prints: error 5, to stderr If formatting elements (e.g. %d) are not found in the first string then util.inspect() is called on each argument and the resulting string values are concatenated. See util.format() for more information.@since ― v0.1.100error)19/*20Output:21task1...22task2...23(FiberFailure) Error: Something went wrong!24*/ Even though execution never reaches code after a failure, TypeScript may still assume that the code below the error is reachable unless you explicitly return after the failure. For example, consider the following scenario where you want to narrow the type of a variable: **Example** (Type Narrowing without Explicit Return) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3type type User = { readonly name: string;}User = {4 readonly name: stringname: string5}6 7// Imagine this function checks a database or an external service8declare function function getUserById(id: string): Effect.EffectgetUserById(id: stringid: string): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect9 10function function greetUser(id: string): Effect.EffectgreetUser(id: stringid: string) {11 return import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: > | YieldWrap>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {12 const const user: User | undefineduser = yield* function getUserById(id: string): Effect.EffectgetUserById(id: stringid)13 14 if (const user: User | undefineduser === var undefinedundefined) {15 // Even though we fail here, TypeScript still thinks16 // 'user' might be undefined later17 yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(`User with id ${id: stringid} not found`)18 }19 20 // @ts-expect-error user is possibly 'undefined'.ts(18048)21 return `Hello, ${const user: User | undefineduser.name: stringname}!`22 })23} In this example, TypeScript still considers `user` possibly `undefined` because there is no explicit return after the failure. To fix this, explicitly return right after calling `Effect.fail`: **Example** (Type Narrowing with Explicit Return) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3type type User = { readonly name: string;}User = {4 readonly name: stringname: string5}6 7declare function function getUserById(id: string): Effect.EffectgetUserById(id: stringid: string): import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.interface EffectThe Effect interface defines a value that describes a workflow or job, which can succeed or fail. Details The Effect interface represents a computation that can model a workflow involving various types of operations, such as synchronous, asynchronous, concurrent, and parallel interactions. It operates within a context of type R, and the result can either be a success with a value of type A or a failure with an error of type E. The Effect is designed to handle complex interactions with external resources, offering advanced features such as fiber-based concurrency, scheduling, interruption handling, and scalability. This makes it suitable for tasks that require fine-grained control over concurrency and error management. To execute an Effect value, you need a Runtime, which provides the environment necessary to run and manage the computation.@since ― 2.0.0@since ― 2.0.0Effect8 9function function greetUser(id: string): Effect.EffectgreetUser(id: stringid: string) {10 return import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: > | YieldWrap>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {11 const const user: User | undefineduser = yield* function getUserById(id: string): Effect.EffectgetUserById(id: stringid)12 13 if (const user: User | undefineduser === var undefinedundefined) {14 // Explicitly return after failing15 return yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const fail: (error: string) => Effect.EffectCreates an Effect that represents a recoverable error. When to Use Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like catchAll or catchTag . Example (Creating a Failed Effect) import { Effect } from "effect" // ┌─── Effect// ▼const failure = Effect.fail( new Error("Operation failed due to network error"))@see ― succeed to create an effect that represents a successful value.@since ― 2.0.0fail(`User with id ${id: stringid} not found`)16 }17 18 // Now TypeScript knows that 'user' is not undefined19 return `Hello, ${const user: Useruser.name: stringname}!`20 })21} Passing `this` -------------- [](#passing-this) In some cases, you might need to pass a reference to the current object (`this`) into the body of your generator function. You can achieve this by utilizing an overload that accepts the reference as the first argument: **Example** (Passing `this` to Generator) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3class class MyClassMyClass {4 readonly MyClass.local: 1local = 15 MyClass.compute: Effect.Effectcompute = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, number>(self: this, f: (this: this, resume: Effect.Adapter) => Generator>, number, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(this, function* () {6 const const n: numbern = this.MyClass.local: 1local + 17 8 yield* import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const log: (...message: ReadonlyArray) => Effect.EffectLogs one or more messages or error causes at the current log level. Details This function provides a simple way to log messages or error causes during the execution of your effects. By default, logs are recorded at the INFO level, but this can be adjusted using other logging utilities (Logger.withMinimumLogLevel). Multiple items, including Cause instances, can be logged in a single call. When logging Cause instances, detailed error information is included in the log output. The log output includes useful metadata like the current timestamp, log level, and fiber ID, making it suitable for debugging and tracking purposes. This function does not interrupt or alter the effect's execution flow. Example import { Cause, Effect } from "effect" const program = Effect.log( "message1", "message2", Cause.die("Oh no!"), Cause.die("Oh uh!")) Effect.runFork(program)// Output:// timestamp=... level=INFO fiber=#0 message=message1 message=message2 cause="Error: Oh no!// Error: Oh uh!"@since ― 2.0.0log(`Computed value: ${const n: numbern}`)9 10 return const n: numbern11 })12}13 14import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const runPromise: (effect: Effect.Effect, options?: { readonly signal?: AbortSignal;} | undefined) => PromiseExecutes an effect and returns the result as a Promise. Details This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect. The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks. When to Use Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results. Example (Running a Successful Effect as a Promise) import { Effect } from "effect" Effect.runPromise(Effect.succeed(1)).then(console.log)// Output: 1 Example (Handling a Failing Effect as a Rejected Promise) import { Effect } from "effect" Effect.runPromise(Effect.fail("my error")).catch(console.error)// Output:// (FiberFailure) Error: my error@see ― runPromiseExit for a version that returns an Exit type instead of rejecting.@since ― 2.0.0runPromise(new constructor MyClass(): MyClassMyClass().MyClass.compute: Effect.Effectcompute).Promise.then(onfulfilled?: ((value: number) => void | PromiseLike) | null | undefined, onrejected?: ((reason: any) => PromiseLike) | null | undefined): Promise<...>Attaches callbacks for the resolution and/or rejection of the Promise.@param ― onfulfilled The callback to execute when the Promise is resolved.@param ― onrejected The callback to execute when the Promise is rejected.@returns ― A Promise for the completion of which ever callback is executed.then(var console: ConsoleThe console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream. A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module. Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information. Example using the global console: console.log('hello world');// Prints: hello world, to stdoutconsole.log('hello %s', 'world');// Prints: hello world, to stdoutconsole.error(new Error('Whoops, something bad happened'));// Prints error message and stack trace to stderr:// Error: Whoops, something bad happened// at [eval]:5:15// at Script.runInThisContext (node:vm:132:18)// at Object.runInThisContext (node:vm:309:38)// at node:internal/process/execution:77:19// at [eval]-wrapper:6:22// at evalScript (node:internal/process/execution:76:60)// at node:internal/main/eval_string:23:3 const name = 'Will Robinson';console.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to stderr Example using the Console class: const out = getStreamSomehow();const err = getStreamSomehow();const myConsole = new console.Console(out, err); myConsole.log('hello world');// Prints: hello world, to outmyConsole.log('hello %s', 'world');// Prints: hello world, to outmyConsole.error(new Error('Whoops, something bad happened'));// Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson';myConsole.warn(`Danger ${name}! Danger!`);// Prints: Danger Will Robinson! Danger!, to err@see ― sourceconsole.Console.log(message?: any, ...optionalParams: any[]): voidPrints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()). const count = 5;console.log('count: %d', count);// Prints: count: 5, to stdoutconsole.log('count:', count);// Prints: count: 5, to stdout See util.format() for more information.@since ― v0.1.100log)15/*16Output:17timestamp=... level=INFO fiber=#0 message="Computed value: 2"18219*/ Adapter Deprecated ------------------ [](#adapter) You may still come across some code snippets that use an adapter, typically indicated by `_` or `$` symbols. In earlier versions of TypeScript, the generator “adapter” function was necessary to ensure correct type inference within generators. This adapter was used to facilitate the interaction between TypeScript’s type system and generator functions. **Example** (Adapter in Older Code) 1import { import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect } from "effect"2 3const const fetchTransactionAmount: Effect.EffectfetchTransactionAmount = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const promise: (evaluate: (signal: AbortSignal) => PromiseLike) => Effect.EffectCreates an Effect that represents an asynchronous computation guaranteed to succeed. Details The provided function (thunk) returns a Promise that should never reject; if it does, the error will be treated as a "defect". This defect is not a standard error but indicates a flaw in the logic that was expected to be error-free. You can think of it similar to an unexpected crash in the program, which can be further managed or logged using tools like catchAllDefect . Interruptions An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API. When to Use Use this function when you are sure the operation will not reject. Example (Delayed Message) import { Effect } from "effect" const delay = (message: string) => Effect.promise( () => new Promise((resolve) => { setTimeout(() => { resolve(message) }, 2000) }) ) // ┌─── Effect// ▼const program = delay("Async operation completed successfully!")@see ― tryPromise for a version that can handle failures.@since ― 2.0.0promise(() => var Promise: PromiseConstructorRepresents the completion of an asynchronous operationPromise.PromiseConstructor.resolve(value: number): Promise (+2 overloads)Creates a new resolved promise for the provided value.@param ― value A promise.@returns ― A promise whose internal state matches the provided promise.resolve(100))4 5// Older usage with an adapter for proper type inference6const const programWithAdapter: Effect.EffectprogramWithAdapter = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, void>(f: (resume: Effect.Adapter) => Generator>, void, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* ($: Effect.Adapter$) {7 const const transactionAmount: numbertransactionAmount = yield* $: Effect.Adapter(self: Effect.Effect) => Effect.Effect (+20 overloads)$(const fetchTransactionAmount: Effect.EffectfetchTransactionAmount)8})9 10// Current usage without an adapter11const const program: Effect.Effectprogram = import Effect@since ― 2.0.0@since ― 2.0.0@since ― 2.0.0Effect.const gen: >, void>(f: (resume: Effect.Adapter) => Generator>, void, never>) => Effect.Effect<...> (+1 overload)Provides a way to write effectful code using generator functions, simplifying control flow and error handling. When to Use Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage. The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end. Example import { Effect } from "effect" const addServiceCharge = (amount: number) => amount + 1 const applyDiscount = ( total: number, discountRate: number): Effect.Effect => discountRate === 0 ? Effect.fail(new Error("Discount rate cannot be zero")) : Effect.succeed(total - (total * discountRate) / 100) const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100)) const fetchDiscountRate = Effect.promise(() => Promise.resolve(5)) export const program = Effect.gen(function* () { const transactionAmount = yield* fetchTransactionAmount const discountRate = yield* fetchDiscountRate const discountedAmount = yield* applyDiscount( transactionAmount, discountRate ) const finalAmount = addServiceCharge(discountedAmount) return `Final amount to charge: ${finalAmount}`})@since ― 2.0.0gen(function* () {12 const const transactionAmount: numbertransactionAmount = yield* const fetchTransactionAmount: Effect.EffectfetchTransactionAmount13}) With advances in TypeScript (v5.5+), the adapter is no longer necessary for type inference. While it remains in the codebase for backward compatibility, it is anticipated to be removed in the upcoming major release of Effect. ---