Effect basics
A service is a named interface for work. A context holds supplied service implementations.¶
An Effect describes work. Build the description, compose it with other Effects, supply its services, then let a runtime execute it.¶
Read the three type parameters
Effect.Effect<A, E, R> describes three things:¶
| Parameter | Meaning | FileInspector’s inspect method |
|---|---|---|
A | Success value | FileStats |
E | Expected failure | FileStatsError |
R | Required services | never |
This method’s full return type is Effect.Effect<FileStats, FileStatsError, never>.
The source omits the final parameter because it defaults to never.¶
export class FileInspector extends Context.Service<
FileInspector,
{
readonly inspect: (
path: string
) => Effect.Effect<FileStats, FileStatsError>;
}
>()("@rat-stack/core/FileInspector", {
make: Effect.gen(function* makeFileInspector() {
const fileSystem = yield* FileSystem.FileSystem;Constructing the inspector needs FileSystem. Its returned method has captured that dependency and does not require it again.¶
R = never means no services remain to supply. It does not mean the computation cannot fail. E = never means no declared expected failures; it does not rule out defects or interruption.¶
A description is not a completed operation
Calling inspector.inspect(path) produces an Effect description. It does not read the file immediately.
The method composes the read with an error translation before a runtime executes either operation.¶
const inspect = Effect.fn("FileInspector.inspect")(function* inspect(
path: string
) {
const content = yield* fileSystem
.readFile(path)
.pipe(
Effect.mapError(
(error) => new FileStatsError({ path, reason: error.message })
)
);
return summarizeBytes(path, content);
});Ordinary JavaScript still evaluates while you build a description. Starting a Promise first, then wrapping it, does not undo that eager work. Keep external work inside the Effect constructor’s callback.¶
Write a sequence with gen; transform it with pipe
Effect.gen composes Effects in generator syntax. yield* obtains a success value or propagates the failure.
The generator describes work for the Effect runtime.¶
Use pipe for short transforms, such as mapping a value, translating a failure, or providing a service.
Use a generator when the next step needs values from earlier steps.¶
- Combinators are functions that combine or transform Effects.¶
Generators and combinators both compose descriptions without running a nested runtime.¶
- In rat-stack, prefer
Effect.genfor inline sequences. UseEffect.fnfor reusable functions with useful tracing names.¶ - Do not write long combinator chains merely to avoid a clear generator.¶
Expected failures and defects are different
An expected failure36 belongs in E, where callers can handle it by its declared type or tag.
A defect is an unexpected execution failure.
Logging a failure does not make the operation successful. Handle expected failures without hiding defects36 shows the file error and its CLI handler.¶
Requirements name services to supply
A requirement is a service the computation needs. A Layer describes how to build a service and supply its dependencies.¶
Layers build implementations and satisfy their construction dependencies.
Getting FileInspector from context requires that service; calling its captured inspect method needs no extra service.
Read service construction16, Layer composition13, and context and requirements9.¶
Run at the application boundary
The CLI builds and transforms a program with pipe, then provides its services and their dependencies. NodeRuntime.runMain executes the final Effect:¶
Effect.provide(
Layer.mergeAll(
Layer.provideMerge(FileInspector.layer, NodeServices.layer),
remoteJoinInterestLayer,
Approval.denyAll
)
)
);
NodeRuntime.runMain(program);The Worker returns a fetch Effect to its Alchemy Worker adapter:¶
return {
fetch: observeRequestIncidents(
events === undefined
? readerApp
: withEventCapture({
captureCity: true,
identityMode,
runInBackground: inBackground,
})(readerApp).pipe(Effect.provideContext(events))
),
};The Worker adapter owns request execution. The domain does not scatter runPromise calls through handlers.¶
In tests, it.effect owns execution of the returned Effect. The test still supplies the services it needs.
See tests through supplied services22. Run Effect at the integration boundary8 covers foreign code, runtime reuse, and disposal.¶
The common wrong first version
Scattering await Effect.runPromise(...) through library methods creates separate execution boundaries where composition should remain intact.
It also turns the expected failure into a rejected Promise rather than preserving the Effect error channel for the caller.
Return the composed Effect and let the application boundary run it.¶
Effect.promise assumes Promise rejection is an unexpected defect.
For an external API with expected failures, use Effect.tryPromise with a translation into a named domain error.
Wrapping an already-started Promise also loses control over when its work begins.¶
Read next
- Effect basics: build a description before running it.¶
- Schemas define the boundary17: define and decode accepted data.¶
- Expected failures and defects36: name failures without hiding crashes.¶
- Service construction16: capture implementation dependencies.¶
- Layer composition13: supply the graph at an entrypoint.¶
- Configuration7: parse supplied settings.¶
- Testing22: prove behavior through supplied services.¶
- Scopes20: acquire resources inside their owner and release them on exit.¶
- Concurrency7: bound work and stop owned children.¶
- HTTP responses7: check status and decode accepted data.¶
- Tracing7: name meaningful operations and inspect export evidence.¶
- Runtime boundaries8: execute through the framework’s Effect integration and connect disposal.¶
Sources
- Arnaldi, Michael. n.d. TypeScript & Effects with Michael Arnaldi. Happy Path 81.. Michael Arnaldi. Historical explanation at 49:15 of success, errors, and requirements; current API evidence comes from the pinned source. Accessed 2026-10-06.
- Arnaldi, Michael. n.d. Why JavaScript Is Broken: How Effect and TypeScript Fixes It.. Michael Arnaldi. Historical explanation at 12:32 of lazy computations that can be transformed before execution. Accessed 2026-10-06.
- Effect contributors. 2026. Effect. Effect 4.0.0.. Effect-TS. Effect<A, E, R>, lazy execution, gen, mapError, fn, and typed failure handling. Accessed 2026-10-06.
- Effect contributors. 2026. Context. Effect 4.0.0.. Effect-TS. Service keys express requirements; supplied context satisfies them. Accessed 2026-10-06.
- Effect contributors. 2026. Effect Vitest integration.. Effect-TS. it.effect owns execution of an Effect returned by a test. Accessed 2026-10-06.
- rat-stack contributors. 2026. rat-stack source snapshot.. rat-stack. FileInspector's method type, CLI composition and execution, Worker fetch Effect, and Effect-aware tests. Accessed 2026-10-06.
Last changed 2026-10-10 in 978dccc. Source on GitHub. Change log.
Linked from
- Accumulate independent errors before writing output. Check every independent job before any job writes an asset.
Effect 4’s Effect.validate evaluates every collection element.
- Agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
Effect basics — An Effect describes work, expected failures, and required services before a runtime executes it.
- Change log. What changed in the files served here, newest first.
Effect basics — edited: docs: point live docs, skills and Brain pages at apps/site
- Concurrent work needs an owner and a bound. Limit active work, retain result order, and stop child work when its owning lifetime ends.
Return to the Effect reading order.¶
- Context and requirements. Effect requirements make a computation's needed services visible in its type.
See Effect basics and infrastructure as effects.¶
- Effect keeps the surfaces on one contract. Schema owns values, projections build interfaces, and Layers supply implementations.
Start with Effect basics, then construct a service and compose its Layers.¶
- Feature flags. Typed feature flags with owners, removal dates, and stable subject rollouts.
Declared Effect actors record lifecycle transitions.
- Full agent guide. An Effect stack so pure (aspirational) Kit Langton will blush.
- Handle expected failures without hiding defects. Declare expected failures, preserve their context, and recover by tag without turning crashes into successful outcomes.
Such a field does not itself turn an expected error into a runtime defect.¶
- HTTP success needs a status check and a decoder. Supply the client, check the response status, decode accepted data, and name failures at the adapter boundary.
Return to the Effect reading order.¶
- learn-rat-stack. Trace a capability through Effect, XState, five projections, the CLI, and Alchemy. Try hosted search and read.
Read Effect basics before this trace if the computation model is new.
- Rat Stack lore | rat-stack. Short, source-grounded notes on the ideas and decisions behind rat-stack.
Effect basics — An Effect describes work, expected failures, and required services before a runtime executes it.
- Run Effect at the integration boundary. Build the runtime where a calling framework enters, reuse its services, and dispose it when that integration ends.
The basics page shows CLI, Worker and test execution boundaries.
- Scopes release resources when work ends. Acquire resources lazily, keep their use inside the owner, and release them after success, failure, or interruption.
Return to the Effect reading order.¶
- Source change history (log.md). The generated change log as Markdown.
Effect basics — edited: docs: point live docs, skills and Brain pages at apps/site
- Structure an Effect codebase by domain. Start with folders for application work, services and Layers in the same file, and startup code that supplies implementations.
Start with Effect basics.¶
- Trace operations where they mean something. Name useful operations, add safe context, and distinguish creating a span from delivering it to a backend.
Return to the Effect reading order.¶
Unlinked mentions (64)
- A service captures its construction dependencies → make describes service construction as an Effect.
- add-a-capability → Effect describes work with typed failures and required dependencies.
- add-a-lifecycle-machine → Effect describes work with typed failures and required dependencies.
- add-a-store → Effect describes work with typed failures and required dependencies.
- Agent rules for rat-stack (AGENTS.md) → Effect 4.0.0 and @effect/platform-node 4.0.0.
- Agents explore, tests remember → The resulting checks use Effect tests.¶
- Analytics → Effect is the library that describes work with typed failures and required services.
- Build and run rat-stack (README.md) → Build an Effect app and its cloud as one typed program.
- CAFE names the Cloudflare, Alchemy, Foldkit and Effect stack → Effect-TS/cafe is a chat app from the Effect organization.
- Capabilities → Effect is a library for describing work with typed failures and required services.
- CascadiaJS 2026: It's time to rethink everything → Theo compares the cloud’s effect on infrastructure with agents’ effect on software production.
- Code snippets quote a pinned source → Effect 4 exposes Arbitrary.schema through effect/Arbitrary.
- Concurrent work needs an owner and a bound → forEach describes one Effect per input and collects results in input order.
- Configuration is a supplied, validated dependency → Effect’s Config.schema can describe more complex validated settings.
- Context and requirements → Sam describes this requirements channel as a way to model permissions before execution, which he calls a static effect.
- Database → Effect describes work with typed failures and required services.
- Dependency injection is the reason to choose Effect → Dillon Mulroy compares Effect with Spring and NestJS:¶
- Devtools → Effect describes work with typed failures and required services.
- Effect + Alchemy peer patterns → At that study date, only alchemy-run/alchemy at 9802260db8f8b5a083c4b85eb7ea31ae1ff8f176 matched both Effect and Alchemy lines: its package is beta.79 and its workspace requires Effect rc.117.
- Effect + Alchemy peers → Pairs: XState then @xstate/effect; first seen then checked.
- Effect 4 study: September 2026 → Other Effect 4 adopters found via GitHub code search for effect/unstable imports: alchemy-run/distilled, MapleTechLabs/maple, tim-smart/receipts, tim-smart/dfx, kitlangton/motel, kitlangton/stack, leonitousconforti/the-moby-effect, crosshatch/crosshatch, anomalyco/effect-http-recorder, Effectful-Tech/clanka.
- Effect Days 2025: Building Effect 4 → Michael describes Effect 4 as a review of choices made in Effect 3, driven by production feedback.
- Effect keeps the surfaces on one contract → Effect Schema owns inputs, outputs, and failures in our shared contract.
- Effect Meetup SF 2023: Why Effect? → A Remix demo contrasts manually added logs, metrics, and traces and nested error handling with Effect context, Schema, spans, metrics, and retry policies.
- Effect's design lineage → John De Goes describes Effect as adapting ZIO’s goals to TypeScript through iterations rather than copying it directly.
- Fence → Effect describes work with typed failures and required services.
- find-peers → Effect describes work with typed failures and required dependencies.
- gardener → Effect describes work with typed failures and required dependencies.
- Handle expected failures without hiding defects → A defect is an unexpected execution failure.¶
- Happy Path 116: Infrastructure as effects → Effect gives Alchemy a pure program: it describes work before execution and can be planned first.
- Happy Path 81: TypeScript and effects → He describes an Effect by its output, predictable failures, and requirements.
- Hexagonal architecture → On the driven side, where the application calls services, Effect Context.Service definitions provide ports for sending interest mail, subscriber intake (SubscriberIntake), and confirmation (SubscriberConfirm).
- HTTP success needs a status check and a decoder → Effect also has native schedules and retry operators.¶
- Infrastructure as effects → A client operation can imply a policy requirement supplied when the function is built.
- investigate-a-failure → Output that looks corrupted may be a side effect of a crash.¶
- keep-or-cut → Effect describes work with typed failures and required dependencies.¶
- Learn mode presents concepts at useful depths → Effect describes the work with typed failures and required services.
- learn-alchemy → limit({ key }) method and turns a failed runtime call into a defect instead of failing open.¶
- learn-rat-stack → Effect describes work with typed failures and required dependencies.¶
- Lifecycles are machines → A side effect is work outside the state description, such as reading a file.
- mdsvex left unified → The fence does not permit rewriting valid prose around a parser defect.¶
- Michael Arnaldi → He describes Effect computations through their outputs, predictable failures, and requirements: the services the work needs.
- Model-based testing → Effect 4’s Arbitrary.array generates command sequences.
- One capability, every surface → Effect Schema provides types and runtime checks for these values.
- One schema, three surfaces → Effect Schema supplies types and runtime checks for these values.¶
- OpenAPI describes the refusal too → Effect’s OpenApi.fromApi derives the document from that HttpApi.¶
- profile-a-worker → One change and its measured effect, or the reason no change is worth it.¶
- Property-based testing → Effect 4 ships its own engine in effect/Arbitrary.
- Purpose and boundaries of rat-stack (VISION.md) → Effect owns the hard parts, Alchemy infers the infrastructure from the code, and the fence raises the floor, so an agent can build it reliably with high-trust.
- Rat King binds agents into one encrypted network → Effect owns contracts, services, and typed failures.¶
- rat-stack → An Effect stack so pure (aspirational) Kit Langton will blush.
- Run Effect at the integration boundary → Effect stays inside the adapter.
- Schema projections: 2026-09-18 history → This study records the proposal and implementation on 2026-09-18 against Effect rc.115.
- Scopes release resources when work ends → The migration adapter makes shutdown failure a defect with orDie.
- ship → Effect: the library for describing work with typed failures and required services.¶
- Structure an Effect codebase by domain → runMain runs the final Effect.
- test-behaviour → prop when the check returns an Effect.¶
- Tests prove behavior through supplied services → effect runs the Effect returned by the test.
- The fence → Effect language-service diagnostics run through TypeScript.
- Trace operations where they mean something → Use annotateSpans when supplying annotations through an enclosing Effect.
- UI behaviour is a scene → A Command is a named side effect.
- uncomplect → No fence yet banning ordinary actor startup; candidate: an Effect-machine startup rule.¶
- Vibe engineering Effect apps → Effect is a TypeScript library for describing work with typed results, failures, and required services.¶
- Worker init runs twice → A Cloudflare Worker’s initialization effect runs twice.