The missing standard library for TypeScript, for writing production-grade software.
npx @tessl/cli install tessl/npm-effect@3.17.0Effect is a comprehensive TypeScript functional programming framework that provides a powerful effect system for managing side effects, ensuring type safety, and supporting advanced concurrency patterns. The core package offers essential primitives for structured side effect management, lightweight dependency injection, resource management, virtual threading, streaming data processing, and schema validation - enabling developers to write robust, production-grade applications with sophisticated error handling and observability features.
npm install effectimport { Effect, Context, Layer } from "effect";Namespace imports (recommended for clarity):
import * as Effect from "effect/Effect";
import * as Context from "effect/Context";
import * as Layer from "effect/Layer";
import * as Array from "effect/Array";
import * as Option from "effect/Option";
import * as Either from "effect/Either";
import * as HashMap from "effect/HashMap";
import * as Fiber from "effect/Fiber";
import * as Stream from "effect/Stream";
import * as Schema from "effect/Schema";
import * as STM from "effect/STM";
import * as Micro from "effect/Micro";
import * as Duration from "effect/Duration";
import * as String from "effect/String";
import * as Number from "effect/Number";For CommonJS:
const { Effect, Context, Layer } = require("effect");Individual functions (directly available at top level):
import { pipe, flow, identity } from "effect";import { Effect, Console } from "effect";
// Creating and running effects
const program = Effect.gen(function* () {
yield* Console.log("Hello Effect!");
const result = yield* Effect.succeed(42);
return result * 2;
});
// Run the effect
const result = await Effect.runPromise(program);
console.log(result); // 84Error handling:
import { Effect, pipe } from "effect";
const riskyOperation = Effect.fail("Something went wrong");
const safeProgram = pipe(
riskyOperation,
Effect.catchAll((error) => Effect.succeed(`Recovered from: ${error}`))
);
const result = await Effect.runPromise(safeProgram);
console.log(result); // "Recovered from: Something went wrong"Effect is built around several foundational concepts:
Effect<A, E, R> type representing computations that may succeed with A, fail with E, and require context RContext for type-safe dependency injectionLayerScope and finalizersStreamThe heart of Effect - defines the fundamental Effect<A, E, R> type and core operations for creating, transforming, and executing effects with structured error handling.
// Core Effect type
interface Effect<out A, out E = never, out R = never> extends Pipeable {}
// Basic effect creation
function succeed<A>(value: A): Effect<A>;
function fail<E>(error: E): Effect<never, E>;
function sync<A>(thunk: LazyArg<A>): Effect<A>;
function async<A, E = never, R = never>(
register: (callback: (effect: Effect<A, E, R>) => void) => void
): Effect<A, E, R>;
// Effect transformations
function map<A, B>(f: (a: A) => B): <E, R>(self: Effect<A, E, R>) => Effect<B, E, R>;
function flatMap<A, B, E2, R2>(
f: (a: A) => Effect<B, E2, R2>
): <E1, R1>(self: Effect<A, E1, R1>) => Effect<B, E1 | E2, R1 | R2>;
// Error handling
function catchAll<E, A2, E2, R2>(
f: (e: E) => Effect<A2, E2, R2>
): <A, R>(self: Effect<A, E, R>) => Effect<A | A2, E2, R | R2>;
// Effect execution
function runPromise<A, E>(effect: Effect<A, E>): Promise<A>;
function runSync<A, E>(effect: Effect<A, E>): A;Core functional programming primitives including pipe operator, function composition, and identity functions for building composable data transformations.
// Function composition and piping
function pipe<A>(a: A): A;
function pipe<A, B>(a: A, ab: (a: A) => B): B;
function pipe<A, B, C>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
// ... additional overloads
function flow<A extends ReadonlyArray<unknown>, B>(ab: (...a: A) => B): (...a: A) => B;
function flow<A extends ReadonlyArray<unknown>, B, C>(
ab: (...a: A) => B,
bc: (b: B) => C
): (...a: A) => C;
// ... additional overloads
function identity<A>(a: A): A;Comprehensive collection of immutable data structures including arrays, hash maps, sets, lists, and specialized structures optimized for functional programming patterns.
// Array operations
declare namespace Array {
function make<A>(...elements: A[]): A[];
function fromIterable<A>(iterable: Iterable<A>): A[];
function map<A, B>(f: (a: A, i: number) => B): (self: ReadonlyArray<A>) => B[];
function filter<A>(predicate: (a: A, i: number) => boolean): (self: ReadonlyArray<A>) => A[];
function reduce<A, B>(b: B, f: (b: B, a: A, i: number) => B): (self: ReadonlyArray<A>) => B;
}
// HashMap operations
declare namespace HashMap {
function empty<K, V>(): HashMap<K, V>;
function make<K, V>(...entries: readonly (readonly [K, V])[]): HashMap<K, V>;
function set<K, V>(key: K, value: V): (self: HashMap<K, V>) => HashMap<K, V>;
function get<K>(key: K): <V>(self: HashMap<K, V>) => Option<V>;
}Type-safe service management and dependency injection system using Context and Tag for organizing and providing services throughout your application.
// Context system
interface Context<in Services> {}
interface Tag<in in out Self, in Type> {}
declare namespace Context {
function make<Services>(): Context<Services>;
function add<T>(tag: Tag<T, T>, service: T): <Services>(self: Context<Services>) => Context<Services | T>;
function get<Services, T>(tag: Tag<T, T>): (self: Context<Services>) => T;
}
// Service creation
function GenericTag<Self, Type = Self>(id: string): Tag<Self, Type>;Modular service composition and resource management system for building applications with managed dependencies and automatic resource cleanup.
interface Layer<out ROut, out E = never, out RIn = never> extends Pipeable {}
declare namespace Layer {
function succeed<T>(tag: Tag<T, T>, resource: T): Layer<T>;
function effect<T, E, R>(tag: Tag<T, T>, effect: Effect<T, E, R>): Layer<T, E, R>;
function scoped<T, E, R>(tag: Tag<T, T>, effect: Effect<T, E, R>): Layer<T, E, Exclude<R, Scope>>;
function provide<RIn, E, ROut>(layer: Layer<RIn, E>): <A, E1, ROut1>(self: Effect<A, E1, RIn | ROut1>) => Effect<A, E | E1, ROut | ROut1>;
}Lightweight virtual threading system with Fiber for structured concurrency, enabling safe parallel execution and resource management.
interface Fiber<out A, out E = never> extends Pipeable {}
declare namespace Fiber {
function succeed<A>(value: A): Fiber<A>;
function fail<E>(error: E): Fiber<never, E>;
function await<A, E>(self: Fiber<A, E>): Effect<Exit<A, E>>;
function join<A, E>(self: Fiber<A, E>): Effect<A, E>;
function interrupt<A, E>(self: Fiber<A, E>): Effect<Exit<A, E>>;
}
// Effect concurrency operations
declare namespace Effect {
function fork<A, E, R>(self: Effect<A, E, R>): Effect<Fiber<A, E>, never, R>;
function forkDaemon<A, E, R>(self: Effect<A, E, R>): Effect<Fiber<A, E>, never, R>;
function race<A, E, R>(self: Effect<A, E, R>): <A2, E2, R2>(that: Effect<A2, E2, R2>) => Effect<A | A2, E | E2, R | R2>;
}Reactive streaming system with Stream for processing infinite sequences of data with back-pressure support and resource safety.
interface Stream<out A, out E = never, out R = never> extends Pipeable {}
declare namespace Stream {
function make<A>(...as: A[]): Stream<A>;
function fromIterable<A>(iterable: Iterable<A>): Stream<A>;
function fromAsyncIterable<A, E>(iterable: AsyncIterable<A>, onError: (e: unknown) => E): Stream<A, E>;
function map<A, B>(f: (a: A) => B): <E, R>(self: Stream<A, E, R>) => Stream<B, E, R>;
function filter<A>(predicate: (a: A) => boolean): <E, R>(self: Stream<A, E, R>) => Stream<A, E, R>;
function take(n: number): <A, E, R>(self: Stream<A, E, R>) => Stream<A, E, R>;
function runCollect<A, E, R>(self: Stream<A, E, R>): Effect<Chunk<A>, E, R>;
}Runtime type validation and transformation system with Schema for parsing, encoding, and validating data with comprehensive error reporting.
interface Schema<in in out A, in in out I = A, out R = never> extends Pipeable {}
declare namespace Schema {
function String: Schema<string>;
function Number: Schema<number>;
function Boolean: Schema<boolean>;
function Array<A, I, R>(item: Schema<A, I, R>): Schema<ReadonlyArray<A>, ReadonlyArray<I>, R>;
function Struct<Fields>(fields: Fields): Schema<{ readonly [K in keyof Fields]: Schema.Type<Fields[K]> }>;
function decode<A, I, R>(schema: Schema<A, I, R>): (u: unknown) => Effect<A, ParseResult, R>;
function encode<A, I, R>(schema: Schema<A, I, R>): (a: A) => Effect<I, ParseResult, R>;
function parse<A, I, R>(schema: Schema<A, I, R>): (u: unknown) => Effect<A, ParseResult, R>;
}Comprehensive error tracking with Cause, structured logging, metrics collection, and distributed tracing for production monitoring.
// Error cause tracking
interface Cause<out E> extends Pipeable {}
declare namespace Cause {
function fail<E>(error: E): Cause<E>;
function die(defect: unknown): Cause<never>;
function interrupt(fiberId: FiberId): Cause<never>;
function parallel<E>(left: Cause<E>, right: Cause<E>): Cause<E>;
function sequential<E>(left: Cause<E>, right: Cause<E>): Cause<E>;
}
// Console operations
declare namespace Console {
function log(...args: ReadonlyArray<any>): Effect<void>;
function error(...args: ReadonlyArray<any>): Effect<void>;
function warn(...args: ReadonlyArray<any>): Effect<void>;
}Error Handling & Observability
// Core types
type LazyArg<A> = () => A;
interface Pipeable {
pipe<Self, Args extends ReadonlyArray<any>, Return>(
this: Self,
...args: Args
): Return;
}
// Option type for nullable values
type Option<A> = None | Some<A>;
interface None extends Pipeable {
readonly _tag: "None";
}
interface Some<A> extends Pipeable {
readonly _tag: "Some";
readonly value: A;
}
// Either type for error/success values
type Either<E, A> = Left<E> | Right<A>;
interface Left<E> extends Pipeable {
readonly _tag: "Left";
readonly left: E;
}
interface Right<A> extends Pipeable {
readonly _tag: "Right";
readonly right: A;
}
// Exit type for effect termination
type Exit<A, E = never> = Success<A> | Failure<E>;
interface Success<A> extends Pipeable {
readonly _tag: "Success";
readonly value: A;
}
interface Failure<E> extends Pipeable {
readonly _tag: "Failure";
readonly cause: Cause<E>;
}