Running Effects

On this page

To execute an Effect, we can utilize a variety of "run" functions provided by the Effect module.

runSync

The runSync function is used to execute an Effect synchronously, which means it runs immediately and returns the result.

ts
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
ts
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

If you check the console, you will see the message "Hello, World!" printed.

runSync will throw an error if your Effect fails or performs any asynchronous tasks. In the latter case, the execution will not proceed beyond that asynchronous task.

ts
import { Effect } from "effect"
 
Effect.runSync(Effect.fail("my error")) // throws
 
Effect.runSync(Effect.promise(() => Promise.resolve(1))) // throws
ts
import { Effect } from "effect"
 
Effect.runSync(Effect.fail("my error")) // throws
 
Effect.runSync(Effect.promise(() => Promise.resolve(1))) // throws

runSyncExit

The runSyncExit function is used to execute an Effect synchronously, which means it runs immediately and returns the result as an Exit (a data type used to describe the result of executing an Effect workflow).

ts
import { Effect } from "effect"
 
const result1 = Effect.runSyncExit(Effect.succeed(1))
console.log(result1)
/*
Output:
{
_id: "Exit",
_tag: "Success",
value: 1
}
*/
 
const result2 = Effect.runSyncExit(Effect.fail("my error"))
console.log(result2)
/*
Output:
{
_id: "Exit",
_tag: "Failure",
cause: {
_id: "Cause",
_tag: "Fail",
failure: "my error"
}
}
*/
ts
import { Effect } from "effect"
 
const result1 = Effect.runSyncExit(Effect.succeed(1))
console.log(result1)
/*
Output:
{
_id: "Exit",
_tag: "Success",
value: 1
}
*/
 
const result2 = Effect.runSyncExit(Effect.fail("my error"))
console.log(result2)
/*
Output:
{
_id: "Exit",
_tag: "Failure",
cause: {
_id: "Cause",
_tag: "Fail",
failure: "my error"
}
}
*/

runSyncExit will throw an error if your Effect performs any asynchronous tasks and the execution will not proceed beyond that asynchronous task.

ts
import { Effect } from "effect"
 
Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))) // throws
ts
import { Effect } from "effect"
 
Effect.runSyncExit(Effect.promise(() => Promise.resolve(1))) // throws

runPromise

The runPromise function is used to execute an Effect and obtain the result as a Promise.

ts
import { Effect } from "effect"
 
Effect.runPromise(Effect.succeed(1)).then(console.log) // Output: 1
ts
import { Effect } from "effect"
 
Effect.runPromise(Effect.succeed(1)).then(console.log) // Output: 1
runPromise will reject with an error if your Effect fails
ts
import { Effect } from "effect"
 
Effect.runPromise(Effect.fail("my error")) // rejects
ts
import { Effect } from "effect"
 
Effect.runPromise(Effect.fail("my error")) // rejects

runPromiseExit

The runPromiseExit function is used to execute an Effect and obtain the result as a Promise that resolves to an Exit (a data type used to describe the result of executing an Effect workflow).

ts
import { Effect } from "effect"
 
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
/*
Output:
{
_id: "Exit",
_tag: "Success",
value: 1
}
*/
 
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
/*
Output:
{
_id: "Exit",
_tag: "Failure",
cause: {
_id: "Cause",
_tag: "Fail",
failure: "my error"
}
}
*/
ts
import { Effect } from "effect"
 
Effect.runPromiseExit(Effect.succeed(1)).then(console.log)
/*
Output:
{
_id: "Exit",
_tag: "Success",
value: 1
}
*/
 
Effect.runPromiseExit(Effect.fail("my error")).then(console.log)
/*
Output:
{
_id: "Exit",
_tag: "Failure",
cause: {
_id: "Cause",
_tag: "Fail",
failure: "my error"
}
}
*/

Cheatsheet

🎨

The recommended approach is to design your program with the majority of its logic as Effects. It's advisable to use the run* functions closer to the "edge" of your program. This approach allows for greater flexibility in executing your program and building sophisticated Effects.

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.

NameGivenTo
runSyncEffect<A, E>A
runSyncExitEffect<A, E>Exit<A, E>
runPromiseEffect<A, E>Promise<A>
runPromiseExitEffect<A, E>Promise<Exit<A, E>>

You can find the complete list of run* functions here.