Free sample lesson ยท Refactoring TypeScript with Effect
Effect Basics
Why replace traditional Promises with functional Effect values?
Lesson 1 of the Wondering course Refactoring TypeScript with Effect
A Value, Not a Promise
A Promise starts running the moment you create it. An Effect does not.
An Effect is a description of work: a plain value you can pass around, combine, or discard before anything executes.
That single shift is what unlocks declarative control flow.
- Promise
- Effect
So the first question is not what Effect does, but why a description beats an eager task.
What Effect Is For
Effect is a TypeScript library built to help developers create complex synchronous and asynchronous programs.
That framing matters for refactoring. You are not adopting a new runtime for a niche case.
You are adopting one representation that covers both halves of your codebase: the instant calculation and the network call.
The Seven Core Features
Effect is often described through seven main features.
They are not separate products. Each one leans on the others, which is why partial adoption still pays off.
- Concurrency: Fiber-based model for highly-scalable, ultra low-latency applications.
- Composability: Small, reusable building blocks.
- Resource Safety: Safe acquisition and release, even on failure.
- Type Safety: Focus on type inference and type safety.
- Error Handling: Structured and reliable built-in handling.
- Asynchronicity: Code looks the same whether synchronous or asynchronous.
- Observability: Full tracing of program execution.
Read them once as a map, then we will take them individually.
Fiber-Based Concurrency
Concurrency in Effect runs on a fiber-based model.
The stated goal is highly-scalable, ultra low-latency applications. Fibers are lightweight, so you are not budgeting them like OS threads.

Notice how many slim fibers fit inside the single runtime boundary, which is what makes highly-scalable, low-latency work possible.
This is the feature that most changes how you think about running many operations at once.
Composability
Composability means building software from small, reusable building blocks.
The stated payoff is software that is highly maintainable, readable, and flexible.
- Whole program: Highly maintainable, readable, and flexible software.
- Composed effect: Smaller effects joined by the same combinators.
- Building block: One small, reusable effect.
Each layer is built from the one inside it
In practice, a large Effect is just smaller Effects joined together. The same combinators work at every size, so a helper you write once keeps working when the program grows.
Resource Safety
Resource safety covers acquisition and release, even when your program fails.
That last clause is the whole point. A file handle, connection, or lock is released on the failure path, not only on the happy path.
- Acquire resource
- Use resource
- Program failed?: Release is guaranteed even when your program fails.
- Release resource
- Done
In hand-written Promise code this is the branch people forget.
Type Safety And Errors
Effect aims to leverage the TypeScript type system to the fullest, with a focus on type inference and type safety.
Error handling is the direct beneficiary. Failures are handled in a structured and reliable manner using built-in capabilities.
- Type Safety
- Error Handling
Compare that to Promise<T>, where a rejection carries no type information at all.
Asynchronicity Looks The Same
Effect lets you write code that looks the same whether it is synchronous or asynchronous.
This removes a familiar refactoring tax. Today, making a synchronous helper async forces async/await through every caller above it.
- Promise code
- Effect code
With Effect, the description does not change shape. The same composition keeps working.
Observability
Effect ships full tracing capabilities.
Because the program is a description that the runtime executes, the runtime can report what actually ran.
- Effect program: A description the runtime executes.
- Runtime execution: Reports what actually ran.
- Fibers: Work spread across many fibers.
That is how you debug and monitor execution of an Effect program, including work spread across many fibers.
Adopting It Safely
You do not rewrite everything. Effect values compose, so you can convert one boundary at a time.
Start where the pain is highest: a function with untyped rejections or a resource that leaks on failure.
- Pick pain: Choose a function with untyped rejections or a leaking resource.
- Wrap it: Express that work as an Effect value instead of a Promise.
- Keep callers: Leave the existing call site unchanged for now.
- Expand: Let composition pull the next layer into Effect.
Wrap it as an Effect, keep the call site unchanged, then let composition pull the next layer in.
Check yourself
An Effect value starts running as soon as it is created.
- True
- False
Answer: False
False. An Effect is a description of work; execution begins only when the runtime runs it. A Promise starts running when it is created.
Effect uses lightweight _____ to run concurrent work and full _____ to report what executed.
Answer: Effect uses lightweight fibers to run concurrent work and full tracing to report what executed.
Fibers provide the lightweight concurrency model. Tracing lets the runtime report and monitor execution, including work across many fibers.
A synchronous TypeScript helper later needs to make a network call. What benefit does Effect provide during this refactoring?
- Callers can keep the same Effect composition
- Every caller must add async/await immediately
- The network call becomes synchronous automatically
- The helper must be rewritten as a Promise first
Answer: Callers can keep the same Effect composition
Effect keeps the program in the same descriptive representation for synchronous and asynchronous work, reducing the need to change every caller to use async/await.
Keep going
This is lesson 1 of 10 in Refactoring TypeScript with Effect. Next up:
- Pure Functions
- Ecosystem Overview
- Data Types
- Typed Failures
- Error Recovery
Wondering turns any topic into short lessons you can read, watch, or listen to, with practice questions and an AI tutor.