How does Effect work under-the-hood?

obadakhalili1 pts1 comments

The Comprehensive Guide to Effect — Build Readable & Reliable TypeScript at Scale

A hands-on guide to Effect

The Comprehensive Guide to Effect

Effect is a TypeScript library for building complex applications that stay<br>readable and reliable as they grow. This guide covers it twice — first what it is and why it<br>exists, then by rebuilding its engine from scratch, piece by piece.

Build Readable & Reliable<br>TypeScript Applications at Scale.

Effect

value

error

needs<br>One type carries all three: what you get, how it fails, what it needs to run.

What this is

Contrary to most sources, this guide focuses less on how to use Effect and more on<br>why it exists and how it works under the hood — down to the loop that runs your<br>code.

It comes in two parts. Ideally read them in order.

PART 1<br>What is Effect

The why. One small program — a web handler reading a user from a database —<br>written twice, plain and with Effect. It walks through three things that get better:<br>invisible errors, threaded dependencies, and async coloring — all of which follow from one<br>idea.

Read Part 1 →

PART 2<br>How it works under the hood

The how. We rebuild a working version of Effect from scratch — six sections build<br>the runtime, a seventh uses it for a real program — showing that an Effect value<br>is just a data structure that a loop walks.

Read Part 2 →

The one idea

A normal function's type tells you what it returns when everything goes right. It stays quiet<br>about two things: how it can fail , and what it needs to run.<br>Those silences turn into surprises — an exception you didn't expect, a dependency you forgot to<br>wire up.

Effect puts all three in one type:

Effect

Success<br>the value you get<br>if it works

Error<br>the ways it can fail,<br>as values

Requirements<br>what it needs<br>from the outside

Three slots: the value, the ways it can fail, and what it needs — all in the type.

The smallest possible before/after — a function that can fail:

Plain — the type hides the failure

const divide = (a: number, b: number): number => {<br>if (b === 0) throw new Error("Cannot divide by zero")<br>return a / b<br>// type says `number`. it does not say "or throws".<br>// you only find the failure by reading the body.

Effect — the failure is in the type

import { Effect } from "effect"

const divide = (a: number, b: number): Effect.Effect =><br>b === 0<br>? Effect.fail(new Error("Cannot divide by zero"))<br>: Effect.succeed(a / b)<br>// the caller sees it without reading the body,<br>// and the compiler makes sure they deal with it.

effect type from number guide needs

Related Articles