Terminal
The @effect/platform/Terminal
module provides an abstraction for interacting with standard input and output, including reading user input and displaying messages on the terminal.
The module provides a single Terminal
tag, which serves as the entry point to reading from and writing to standard input and standard output.
1import { import Terminal
Terminal } from "@effect/platform"2import { import Effect
Effect } from "effect"3
4const const program: Effect.Effect<void, never, Terminal.Terminal>
program = import Effect
Effect.const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>>, void>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>>, void, never>) => Effect.Effect<...> (+1 overload)
gen(function* () {5 const const terminal: Terminal.Terminal
terminal = yield* import Terminal
Terminal.const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal6
7 // use `terminal` to interact with standard input and output8})
1import { import Terminal
Terminal } from "@effect/platform"2import { import NodeRuntime
NodeRuntime, import NodeTerminal
NodeTerminal } from "@effect/platform-node"3import { import Effect
Effect } from "effect"4
5const const program: Effect.Effect<void, PlatformError, Terminal.Terminal>
program = import Effect
Effect.const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<void, PlatformError, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {6 const const terminal: Terminal.Terminal
terminal = yield* import Terminal
Terminal.const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal7 yield* const terminal: Terminal.Terminal
terminal.(property) Terminal.display: (text: string) => Effect.Effect<void, PlatformError>
Displays text to the the default standard output.
display("a message\n")8})9
10import NodeRuntime
NodeRuntime.const runMain: RunMain
<PlatformError, void>(effect: Effect.Effect<void, PlatformError, never>, options?: {
readonly disableErrorReporting?: boolean | undefined;
readonly disablePrettyLogger?: boolean | undefined;
readonly teardown?: Teardown | undefined;
}) => void (+1 overload)
runMain(const program: Effect.Effect<void, PlatformError, Terminal.Terminal>
program.(method) Pipeable.pipe<Effect.Effect<void, PlatformError, Terminal.Terminal>, Effect.Effect<void, PlatformError, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<void, PlatformError, Terminal.Terminal>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(import Effect
Effect.const provide: <Terminal.Terminal, never, never>(layer: Layer<Terminal.Terminal, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)
Splits the context into two parts, providing one part using the
specified layer/context/runtime and leaving the remainder `R0`
provide(import NodeTerminal
NodeTerminal.const layer: Layer<Terminal.Terminal, never, never>
layer)))11// Output: "a message"
1import { import Terminal
Terminal } from "@effect/platform"2import { import NodeRuntime
NodeRuntime, import NodeTerminal
NodeTerminal } from "@effect/platform-node"3import { import Effect
Effect } from "effect"4
5const const program: Effect.Effect<void, Terminal.QuitException, Terminal.Terminal>
program = import Effect
Effect.const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<string, Terminal.QuitException, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {6 const const terminal: Terminal.Terminal
terminal = yield* import Terminal
Terminal.const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal7 const const input: string
input = yield* const terminal: Terminal.Terminal
terminal.(property) Terminal.readLine: Effect.Effect<string, Terminal.QuitException, never>
Reads a single line from the default standard input.
readLine8 namespace console
var console: Console
The `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`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and
[`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). 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`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for
more information.
Example using the global `console`:
```js
console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.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:
```js
const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.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
```
console.(method) Console.log(message?: any, ...optionalParams: any[]): void
Prints 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)`](http://man7.org/linux/man-pages/man3/printf.3.html)
(the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)).
```js
const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout
```
See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.
log(`input: ${const input: string
input}`)9})10
11import NodeRuntime
NodeRuntime.const runMain: RunMain
<Terminal.QuitException, void>(effect: Effect.Effect<void, Terminal.QuitException, never>, options?: {
readonly disableErrorReporting?: boolean | undefined;
readonly disablePrettyLogger?: boolean | undefined;
readonly teardown?: Teardown | undefined;
}) => void (+1 overload)
runMain(const program: Effect.Effect<void, Terminal.QuitException, Terminal.Terminal>
program.(method) Pipeable.pipe<Effect.Effect<void, Terminal.QuitException, Terminal.Terminal>, Effect.Effect<void, Terminal.QuitException, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(import Effect
Effect.const provide: <Terminal.Terminal, never, never>(layer: Layer<Terminal.Terminal, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)
Splits the context into two parts, providing one part using the
specified layer/context/runtime and leaving the remainder `R0`
provide(import NodeTerminal
NodeTerminal.const layer: Layer<Terminal.Terminal, never, never>
layer)))12// Input: "hello"13// Output: "input: hello"
This example demonstrates how to create a complete number-guessing game by reading input from the terminal and providing feedback to the user. The game continues until the user guesses the correct number.
1import { import Terminal
Terminal } from "@effect/platform"2import type { (alias) type PlatformError = BadArgument | SystemError
(alias) namespace PlatformError
import PlatformError
PlatformError } from "@effect/platform/Error"3import { import Effect
Effect, import Option
Option, import Random
Random } from "effect"4import { import NodeRuntime
NodeRuntime, import NodeTerminal
NodeTerminal } from "@effect/platform-node"5
6const const secret: Effect.Effect<number, never, never>
secret = import Random
Random.const nextIntBetween: (min: number, max: number) => Effect.Effect<number>
Returns the next integer value in the specified range from the
pseudo-random number generator.
nextIntBetween(1, 100)7
8const const parseGuess: (input: string) => Option.None<number> | Option.Some<number>
parseGuess = ((parameter) input: string
input: string) => {9 const const n: number
n = function parseInt(string: string, radix?: number): number
Converts a string to an integer.
parseInt((parameter) input: string
input, 10)10 return function isNaN(number: number): boolean
Returns a Boolean value that indicates whether a value is the reserved value NaN (not a number).
isNaN(const n: number
n) || const n: number
n < 1 || const n: number
n > 100 ? import Option
Option.const none: <never>() => Option.Option<never>
Creates a new `Option` that represents the absence of a value.
none() : import Option
Option.const some: <number>(value: number) => Option.Option<number>
Creates a new `Option` that wraps the given value.
some(const n: number
n)11}12
13const const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display = ((parameter) message: string
message: string) =>14 import Effect
Effect.const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<void, PlatformError, never>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {15 const const terminal: Terminal.Terminal
terminal = yield* import Terminal
Terminal.const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal16 yield* const terminal: Terminal.Terminal
terminal.(property) Terminal.display: (text: string) => Effect.Effect<void, PlatformError>
Displays text to the the default standard output.
display(`${(parameter) message: string
message}\n`)17 })18
19const const prompt: Effect.Effect<string, PlatformError | Terminal.QuitException, Terminal.Terminal>
prompt = import Effect
Effect.const gen: <YieldWrap<Tag<Terminal.Terminal, Terminal.Terminal>> | YieldWrap<Effect.Effect<void, PlatformError, never>> | YieldWrap<...>, string>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {20 const const terminal: Terminal.Terminal
terminal = yield* import Terminal
Terminal.const Terminal: Tag<Terminal.Terminal, Terminal.Terminal>
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal21 yield* const terminal: Terminal.Terminal
terminal.(property) Terminal.display: (text: string) => Effect.Effect<void, PlatformError>
Displays text to the the default standard output.
display("Enter a guess: ")22 return yield* const terminal: Terminal.Terminal
terminal.(property) Terminal.readLine: Effect.Effect<string, Terminal.QuitException, never>
Reads a single line from the default standard input.
readLine23})24
25const const answer: Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>
answer: import Effect
Effect.interface Effect<out A, out E = never, out R = never>
namespace Effect
The `Effect` interface defines a value that lazily describes a workflow or job.
The workflow requires some context `R`, and may fail with an error of type `E`,
or succeed with a value of type `A`.
`Effect` values model resourceful interaction with the outside world, including
synchronous, asynchronous, concurrent, and parallel interaction. They use a
fiber-based concurrency model, with built-in support for scheduling, fine-grained
interruption, structured concurrency, and high scalability.
To run an `Effect` value, you need a `Runtime`, which is a type that is capable
of executing `Effect` values.
Effect<26 number,27 import Terminal
Terminal.class QuitException
A `QuitException` represents an exception that occurs when a user attempts to
quit out of a `Terminal` prompt for input (usually by entering `ctrl`+`c`).
QuitException | (alias) type PlatformError = BadArgument | SystemError
(alias) namespace PlatformError
import PlatformError
PlatformError,28 import Terminal
Terminal.interface Terminal
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal29> = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>> | YieldWrap<Effect.Effect<string, PlatformError | Terminal.QuitException, Terminal.Terminal>> | YieldWrap<...>, number>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {30 const const input: string
input = yield* const prompt: Effect.Effect<string, PlatformError | Terminal.QuitException, Terminal.Terminal>
prompt31 const const guess: Option.None<number> | Option.Some<number>
guess = const parseGuess: (input: string) => Option.None<number> | Option.Some<number>
parseGuess(const input: string
input)32 if (import Option
Option.const isNone: <number>(self: Option.Option<number>) => self is Option.None<number>
Determine if a `Option` is a `None`.
isNone(const guess: Option.None<number> | Option.Some<number>
guess)) {33 yield* const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display("You must enter an integer from 1 to 100")34 return yield* const answer: Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>
answer35 }36 return const guess: Option.Some<number>
guess.(property) Some<number>.value: number
value37})38
39const const check: <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>) => Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
check = <(type parameter) A in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
A, (type parameter) E in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
E, (type parameter) R in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
R>(40 (parameter) secret: number
secret: number,41 (parameter) guess: number
guess: number,42 (parameter) ok: Effect.Effect<A, E, R>
ok: import Effect
Effect.interface Effect<out A, out E = never, out R = never>
namespace Effect
The `Effect` interface defines a value that lazily describes a workflow or job.
The workflow requires some context `R`, and may fail with an error of type `E`,
or succeed with a value of type `A`.
`Effect` values model resourceful interaction with the outside world, including
synchronous, asynchronous, concurrent, and parallel interaction. They use a
fiber-based concurrency model, with built-in support for scheduling, fine-grained
interruption, structured concurrency, and high scalability.
To run an `Effect` value, you need a `Runtime`, which is a type that is capable
of executing `Effect` values.
Effect<(type parameter) A in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
A, (type parameter) E in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
E, (type parameter) R in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
R>,43 (parameter) ko: Effect.Effect<A, E, R>
ko: import Effect
Effect.interface Effect<out A, out E = never, out R = never>
namespace Effect
The `Effect` interface defines a value that lazily describes a workflow or job.
The workflow requires some context `R`, and may fail with an error of type `E`,
or succeed with a value of type `A`.
`Effect` values model resourceful interaction with the outside world, including
synchronous, asynchronous, concurrent, and parallel interaction. They use a
fiber-based concurrency model, with built-in support for scheduling, fine-grained
interruption, structured concurrency, and high scalability.
To run an `Effect` value, you need a `Runtime`, which is a type that is capable
of executing `Effect` values.
Effect<(type parameter) A in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
A, (type parameter) E in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
E, (type parameter) R in <A, E, R>(secret: number, guess: number, ok: Effect.Effect<A, E, R>, ko: Effect.Effect<A, E, R>): Effect.Effect<A, PlatformError | E, Terminal.Terminal | R>
R>44) =>45 import Effect
Effect.const gen: <YieldWrap<Effect.Effect<void, PlatformError, Terminal.Terminal>> | YieldWrap<Effect.Effect<A, E, R>>, A>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {46 if ((parameter) guess: number
guess > (parameter) secret: number
secret) {47 yield* const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display("Too high")48 return yield* (parameter) ko: Effect.Effect<A, E, R>
ko49 } else if ((parameter) guess: number
guess < (parameter) secret: number
secret) {50 yield* const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display("Too low")51 return yield* (parameter) ko: Effect.Effect<A, E, R>
ko52 } else {53 return yield* (parameter) ok: Effect.Effect<A, E, R>
ok54 }55 })56
57const const end: Effect.Effect<void, PlatformError, Terminal.Terminal>
end = const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display("You guessed it!")58
59const const loop: (secret: number) => Effect.Effect<void, Terminal.QuitException | PlatformError, Terminal.Terminal>
loop = (60 (parameter) secret: number
secret: number61): import Effect
Effect.interface Effect<out A, out E = never, out R = never>
namespace Effect
The `Effect` interface defines a value that lazily describes a workflow or job.
The workflow requires some context `R`, and may fail with an error of type `E`,
or succeed with a value of type `A`.
`Effect` values model resourceful interaction with the outside world, including
synchronous, asynchronous, concurrent, and parallel interaction. They use a
fiber-based concurrency model, with built-in support for scheduling, fine-grained
interruption, structured concurrency, and high scalability.
To run an `Effect` value, you need a `Runtime`, which is a type that is capable
of executing `Effect` values.
Effect<62 void,63 import Terminal
Terminal.class QuitException
A `QuitException` represents an exception that occurs when a user attempts to
quit out of a `Terminal` prompt for input (usually by entering `ctrl`+`c`).
QuitException | (alias) type PlatformError = BadArgument | SystemError
(alias) namespace PlatformError
import PlatformError
PlatformError,64 import Terminal
Terminal.interface Terminal
A `Terminal` represents a command-line interface which can read input from a
user and display messages to a user.
Terminal65> =>66 import Effect
Effect.const gen: <YieldWrap<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {67 const const guess: number
guess = yield* const answer: Effect.Effect<number, PlatformError | Terminal.QuitException, Terminal.Terminal>
answer68 return yield* const check: <void, PlatformError | Terminal.QuitException, Terminal.Terminal>(secret: number, guess: number, ok: Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>, ko: Effect.Effect<...>) => Effect.Effect<...>
check(69 (parameter) secret: number
secret,70 const guess: number
guess,71 const end: Effect.Effect<void, PlatformError, Terminal.Terminal>
end,72 import Effect
Effect.const suspend: <void, PlatformError | Terminal.QuitException, Terminal.Terminal>(effect: LazyArg<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>>) => Effect.Effect<...>
Creates an `Effect` that defers the creation of another effect until it is needed.
Useful for lazy evaluation, handling circular dependencies, or avoiding eager execution in recursive functions.
suspend(() => const loop: (secret: number) => Effect.Effect<void, Terminal.QuitException | PlatformError, Terminal.Terminal>
loop((parameter) secret: number
secret))73 )74 })75
76const const game: Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>
game = import Effect
Effect.const gen: <YieldWrap<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>>, void>(f: (resume: Effect.Adapter) => Generator<...>) => Effect.Effect<...> (+1 overload)
gen(function* () {77 yield* const display: (message: string) => Effect.Effect<void, PlatformError, Terminal.Terminal>
display(78 `We have selected a random number between 1 and 100.79See if you can guess it in 10 turns or fewer.80We'll tell you if your guess was too high or too low.`81 )82 yield* const loop: (secret: number) => Effect.Effect<void, Terminal.QuitException | PlatformError, Terminal.Terminal>
loop(yield* const secret: Effect.Effect<number, never, never>
secret)83})84
85import NodeRuntime
NodeRuntime.const runMain: RunMain
<PlatformError | Terminal.QuitException, void>(effect: Effect.Effect<void, PlatformError | Terminal.QuitException, never>, options?: {
readonly disableErrorReporting?: boolean | undefined;
readonly disablePrettyLogger?: boolean | undefined;
readonly teardown?: Teardown | undefined;
}) => void (+1 overload)
runMain(const game: Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>
game.(method) Pipeable.pipe<Effect.Effect<void, PlatformError | Terminal.QuitException, Terminal.Terminal>, Effect.Effect<void, PlatformError | Terminal.QuitException, never>>(this: Effect.Effect<...>, ab: (_: Effect.Effect<...>) => Effect.Effect<...>): Effect.Effect<...> (+21 overloads)
pipe(import Effect
Effect.const provide: <Terminal.Terminal, never, never>(layer: Layer<Terminal.Terminal, never, never>) => <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<...> (+9 overloads)
Splits the context into two parts, providing one part using the
specified layer/context/runtime and leaving the remainder `R0`
provide(import NodeTerminal
NodeTerminal.const layer: Layer<Terminal.Terminal, never, never>
layer)))