# Effect Essentials

An `Effect<A, E, R>` is a lazy, immutable description of a program. It says: when
run, this computation may **succeed** with a value of type `A`, **fail** with an
error of type `E`, and requires a set of services `R` to be provided. Nothing
happens until you hand the description to a runtime (see [Runtime](https://effect.plants.sh/runtime/)) -
building effects is pure, running them is the side effect.

This section covers the everyday mechanics of writing that description: the two
ways to author effectful code, how to lift existing values and APIs into
`Effect`, and how to sequence and branch between effects.

```ts
import { Effect } from "effect"

// A small program: take a number, double it, log it, return it.
const program = Effect.gen(function*() {
  const n = yield* Effect.succeed(21)
  const doubled = n * 2
  yield* Effect.log(`Result: ${doubled}`)
  return doubled
})

// `program` is just a value - a description. Running it produces the effect.
Effect.runFork(program)
```

## How to write Effect code

There are two idiomatic styles, and you will mix them constantly.

- **`Effect.gen`** lets you write effectful code in an imperative,
  `async`/`await`-like style. You `yield*` an effect to get its success value,
  and the generator threads errors and services through for you. Reach for it
  whenever a computation has several sequential steps or local variables.

- **`pipe` and combinators** (`Effect.map`, `Effect.flatMap`, `Effect.tap`, ...)
  compose effects as data transformations. This style shines for short
  transformations and for attaching cross-cutting behaviour (logging, spans,
  retries) to an existing effect.

When you write a **function that returns an Effect**, do not write a plain
function that returns `Effect.gen(...)`. Use **`Effect.fn("name")`** instead - it
gives you the generator syntax plus an automatic tracing span and better stack
traces.

## In this section

- [Using generators](https://effect.plants.sh/essentials/using-generators/) - write imperative-style
  effect code with `Effect.gen` and `yield*`.
- [Effect.fn](https://effect.plants.sh/essentials/effect-fn/) - the right way to define functions that
  return effects, with named spans.
- [Creating effects](https://effect.plants.sh/essentials/creating-effects/) - lift plain values, sync
  code, promises, nullable values, and callbacks into `Effect`.
- [Building pipelines](https://effect.plants.sh/essentials/building-pipelines/) - compose effects with
  `pipe`: `map`, `flatMap`, `andThen`, `tap`, `as`.
- [Control flow](https://effect.plants.sh/essentials/control-flow/) - conditional and looping
  combinators: `when`, `forEach`, `whileLoop`, and friends.

Once you are comfortable here, move on to [Error Management](https://effect.plants.sh/error-management/),
[Services & Layers](https://effect.plants.sh/services-and-layers/), and [Runtime](https://effect.plants.sh/runtime/).