Importing Effect
Almost everything you need lives in a single package: effect. It bundles the
core library — Effect, Schema, Stream, Layer, and dozens of data types —
plus a set of unstable modules for building real systems (HTTP, CLI, RPC,
SQL, AI, and more). This page explains the package layout and how to import each
kind of module.
// Core modules: named imports from the package root.import { Console, Context, Effect, Layer, Schema, Stream } from "effect"
// Unstable modules: imported from "effect/unstable/<area>".import { HttpClient } from "effect/unstable/http"
// Platform packages: runtime-specific bindings live in their own package.import { NodeRuntime } from "@effect/platform-node"Each module is a namespace whose members you call as functions — for example
Effect.gen, Effect.succeed, Schema.String, Stream.fromIterable. You
rarely import individual functions; you import the module and reach into it.
Core modules
Section titled “Core modules”The core of Effect is exported from the package root, so you import the modules you need as named imports:
import { Effect, Layer, Schema } from "effect"
const program = Effect.succeed(42)These names — Effect, Layer, Schema, Stream, Context, Console,
Clock, Cause, Exit, and many more — are all top-level modules. You will
see them throughout the documentation.
Unstable modules
Section titled “Unstable modules”Modules that are still stabilizing — the building blocks for HTTP servers and
clients, CLIs, RPC, SQL, AI, clustering, and more — live under
effect/unstable/<area>. They are part of the same effect package; the
unstable segment simply signals that their APIs may change before they are
promoted to the stable core.
// Named import from the area's barrel (recommended).import { HttpClient, HttpClientRequest } from "effect/unstable/http"
// Or import a single module deeply, which is best for tree shaking.import * as HttpClient from "effect/unstable/http/HttpClient"The available areas include http, httpapi, cli, rpc, sql, ai,
cluster, and others. Each gets its own documentation section — see
HTTP Client, HTTP API, CLI,
RPC, SQL, AI, and Cluster.
Platform packages
Section titled “Platform packages”Effect itself is runtime-agnostic. Bindings that talk to a specific runtime —
its filesystem, process signals, and HTTP server — live in separate platform
packages such as @effect/platform-node (Node.js) and @effect/platform-bun
(Bun). The most common thing you’ll import is runMain, the production entry
point for long-running programs:
import { Effect } from "effect"import { NodeRuntime } from "@effect/platform-node"
const program = Effect.log("running")
// `runMain` installs signal handlers, runs finalizers on shutdown, and reports// errors — the right way to run an application (vs. `Effect.runPromise` for// scripts and quick experiments).NodeRuntime.runMain(program)See Platform and Runtime for details.
Named imports vs. namespace imports
Section titled “Named imports vs. namespace imports”You can import a core module either as a named import or as a namespace import from its deep path. Both give you the same module:
// Named import — the common, readable choice.import { Effect } from "effect"
// Namespace import — equivalent, occasionally useful for bundler tree shaking.import * as Effect from "effect/Effect"Prefer the named form for readability. The deep namespace form
(effect/Effect, effect/unstable/http/HttpClient) can help bundlers that lack
deep scope analysis eliminate unused code, but modern bundlers like Rollup and
Webpack 5+ handle named imports from "effect" well.
Why functions, not methods
Section titled “Why functions, not methods”Effect modules expose functions (Effect.map(self, f)) rather than methods
on a prototype. There are two reasons:
- Tree shaking. Only the functions you actually import end up in your bundle. Methods attached to a prototype cannot be removed even when unused.
- Extendibility. Anyone can add a new operation as a plain function without patching a prototype, which keeps the ecosystem composable.
To chain functions readably, use .pipe, which threads a value through a series
of transformations left to right:
import { Effect } from "effect"
const program = Effect.succeed(1).pipe( Effect.map((n) => n + 1), Effect.flatMap((n) => Effect.succeed(n * 10)), Effect.tap((n) => Effect.log(`result: ${n}`)))Now that you know how to import things, head to Effect Essentials to start creating and running effects, or jump straight into the Quickstart.