Skip to content

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.

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.

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.

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.

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.

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.