# Launching Layers (Layer.launch)

Many real applications are not "compute a value and exit" programs — they are
**long-running**: an HTTP server, a queue consumer, a set of background workers
that should stay up until the process is stopped. `Layer.launch` is built for
exactly this shape. It takes a [layer](https://effect.plants.sh/services-and-layers/) describing your
whole application, builds it (running all the layer's startup logic and
acquiring its resources), and then *never returns* — it keeps the process alive
until interrupted, tearing every resource down cleanly on shutdown.

```ts
// main.ts
import { NodeHttpServer, NodeRuntime } from "@effect/platform-node"
import { Effect, Layer } from "effect"
import { HttpRouter, HttpServerResponse } from "effect/unstable/http"
import { createServer } from "node:http"

// Describe the app as routes...
const HealthRoutes = HttpRouter.use(
  Effect.fn(function*(router) {
    yield* router.add("GET", "/health", Effect.succeed(HttpServerResponse.text("ok")))
    yield* router.add("GET", "/healthz", Effect.succeed(HttpServerResponse.text("ok")))
  })
)

// ...then as a server *layer*, with the Node HTTP backend provided.
const HttpServerLive = HttpRouter.serve(HealthRoutes).pipe(
  Layer.provide(NodeHttpServer.layer(createServer, { port: 3000 }))
)

// Layer.launch converts the layer into a long-running Effect<never, E, RIn>:
// it builds the layer, then blocks forever until interrupted.
const main = Layer.launch(HttpServerLive)

// runMain makes it the process root, with signal handling + error reporting.
NodeRuntime.runMain(main)
```

## How it works

`Layer.launch(layer)` does two things:

1. **Builds the layer** inside a scope — every service's acquisition effect
   runs, side effects fire, the server starts listening.
2. **Waits forever** (`Effect.never`) so the process stays alive. The resulting
   effect has type `Effect<never, E, RIn>`: it never *succeeds* (there is no
   value to produce), it may *fail* with the layer's error type `E`, and `RIn`
   is whatever the layer still needs you to provide.

Under the hood it is a one-liner over [`Layer.build`](#layerbuildlayer):

```ts
// Effectively:
const launch = <RIn, E, ROut>(self: Layer.Layer<ROut, E, RIn>) =>
  Effect.scoped(Effect.andThen(Layer.build(self), Effect.never))
```

Because the build happens inside a scope, when the launched effect is
interrupted — say by `SIGTERM` under [`runMain`](https://effect.plants.sh/runtime/run-main/) — every
layer finalizer runs in reverse order. Your server stops accepting connections,
your database pool drains, your workers shut down. This is the payoff of
modelling the app as layers: startup and graceful shutdown come for free.
**Layer.launch never succeeds:** The success channel of `Layer.launch` is `never`. The effect runs until it is
  interrupted or fails — it has no successful exit. That is why the type is
  `Effect<never, E, RIn>`: there is no value to `await` or `tap` on success,
  only an error path or interruption. If you need the built services as a value,
  reach for [`Layer.build`](#layerbuildlayer) instead.
**launch vs. build:** `Layer.build` gives you the layer's services as a value inside a scope so you
  can *use* them. `Layer.launch` instead assumes the layer *is* the application
  — there is nothing more to do but keep it running. Use `launch` when the
  services do their work as a side effect of being built (a server that starts
  listening, a worker that starts looping).

## Composing the whole app

The pattern scales: merge every part of your application — server, background
workers, schedulers — into a single layer, then launch it. Each piece is an
ordinary layer, so it can declare its own dependencies and finalizers.

```ts
import { NodeRuntime } from "@effect/platform-node"
import { Effect, Layer } from "effect"

// A background worker expressed as a layer. forkScoped keeps the loop tied to
// the layer's scope, so it is interrupted on shutdown.
const Worker = Layer.effectDiscard(
  Effect.gen(function*() {
    yield* Effect.logInfo("worker online")
    yield* Effect.forkScoped(
      Effect.gen(function*() {
        while (true) {
          yield* Effect.logInfo("processing batch")
          yield* Effect.sleep("5 seconds")
        }
      })
    )
  })
)

// Imagine HttpServerLive from the example above. Merge everything the app runs.
declare const HttpServerLive: Layer.Layer<never>
const AppLive = Layer.mergeAll(HttpServerLive, Worker)

// One launch, one runMain. The app stays up until interrupted, then every
// layer's finalizers run in reverse for a clean shutdown.
NodeRuntime.runMain(Layer.launch(AppLive))
```

## Handling failure at the boundary

`Layer.launch` returns a normal effect, so you can attach error handling before
running it — useful for logging why an app shut down:

```ts
import { Console, Effect, Layer } from "effect"

declare const AppLive: Layer.Layer<never, Error>

const application = Layer.launch(AppLive).pipe(
  Effect.tapError((error) => Console.error(`Application failed: ${error}`))
)
```

## When to use it

Use `Layer.launch` whenever your application is naturally expressed as layers
and should run until stopped — servers, workers, daemons. Combine it with
[`NodeRuntime.runMain` / `BunRuntime.runMain`](https://effect.plants.sh/runtime/run-main/) for the full
production entrypoint: graceful signal-driven shutdown, error reporting, and
correct exit codes. For one-shot programs that compute a result and exit, you do
not need `launch` — just provide the layers and run the effect directly.

## Building layers manually

`Layer.launch` is the right tool when the layer *is* the application. Sometimes
you instead want the layer's services as a **`Context` value** — to read a
service out of it, to drive it from imperative code, or to build several layers
under shared lifetimes. The `build` family does exactly that: it materializes a
layer into a `Context.Context<ROut>` whose resources live for the duration of a
[`Scope`](https://effect.plants.sh/resource-management/scope-and-finalizers/).

These are the building blocks. [`ManagedRuntime`](https://effect.plants.sh/services-and-layers/managed-runtime/)
wraps `build` plus a `MemoMap` into a reusable runtime, and `Layer.launch` sits
on top of `build` by holding the scope open with `Effect.never`. Reach for these
APIs directly only when neither of those higher-level helpers fits.

### `Layer.launch(layer)`

Builds the layer and keeps it alive until the returned effect is interrupted.
Returns `Effect<never, E, RIn>` — the success channel is `never`.

```ts
import { Console, Context, Effect, Layer } from "effect"

class Server extends Context.Service<Server, { readonly port: number }>()("Server") {}

const ServerLive = Layer.effect(
  Server,
  Effect.gen(function*() {
    yield* Console.log("listening on :3000")
    return { port: 3000 }
  })
)

// Build Server, then block forever; finalizers run on interruption.
const main = Layer.launch(ServerLive)
// => Effect<never, never, never>
```

### `Layer.build(layer)`

Builds a layer into a `Context` value, automatically using the ambient `Scope`
and `MemoMap` from the current fiber. Has type
`Effect<Context.Context<ROut>, E, RIn | Scope.Scope>`, so the caller must
provide a `Scope` (commonly via `Effect.scoped`).

```ts
import { Context, Effect, Layer } from "effect"

class Database extends Context.Service<Database, {
  readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}

const DatabaseLive = Layer.succeed(Database, {
  query: (sql) => Effect.succeed(`rows for ${sql}`)
})

const program = Effect.gen(function*() {
  // Materialize the layer into a Context within the current scope.
  const context = yield* Layer.build(DatabaseLive)
  const db = Context.get(context, Database)
  return yield* db.query("SELECT 1")
}).pipe(Effect.scoped)
// => Effect<string, never, never>
```

### `Layer.buildWithScope(layer, scope)`

Builds a layer using an explicit `Scope` you supply, rather than the ambient
one. The layer's resources are released when that scope is closed. Useful when
you need to control resource lifetime precisely. Also available data-last:
`Layer.buildWithScope(scope)`.

```ts
import { Context, Effect, Exit, Layer, Scope } from "effect"

class Database extends Context.Service<Database, {
  readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}

const DatabaseLive = Layer.succeed(Database, {
  query: (sql) => Effect.succeed(`rows for ${sql}`)
})

const program = Effect.gen(function*() {
  const scope = yield* Scope.make()
  // Resources tied to `scope`, not to the surrounding effect.
  const context = yield* Layer.buildWithScope(DatabaseLive, scope)
  const db = Context.get(context, Database)
  const result = yield* db.query("SELECT 1")
  yield* Scope.close(scope, Exit.succeed(undefined)) // <- explicit teardown
  return result
})
// => Effect<string, never, never>
```

### `Layer.buildWithMemoMap(layer, memoMap, scope)`

The lowest-level builder: builds a layer using an explicit `MemoMap` and `Scope`.
Building the *same* layer twice with the same `MemoMap` reuses the first
construction instead of acquiring it again — this is how shared dependencies
(one `Database`, many consumers) stay singletons. Also available data-last:
`Layer.buildWithMemoMap(memoMap, scope)`.

```ts
import { Context, Effect, Layer } from "effect"

class Database extends Context.Service<Database, {
  readonly query: (sql: string) => Effect.Effect<string>
}>()("Database") {}

const DatabaseLive = Layer.effect(
  Database,
  Effect.sync(() => {
    console.log("constructing Database")
    return { query: (sql: string) => Effect.succeed(sql) }
  })
)

const program = Effect.gen(function*() {
  const memoMap = yield* Layer.makeMemoMap
  const scope = yield* Effect.scope

  // First build constructs Database...
  yield* Layer.buildWithMemoMap(DatabaseLive, memoMap, scope)
  // ...second build with the same memoMap reuses it (no second log).
  const ctx = yield* Layer.buildWithMemoMap(DatabaseLive, memoMap, scope)
  return Context.get(ctx, Database)
}).pipe(Effect.scoped)
// => logs "constructing Database" exactly once
```

### `Layer.makeMemoMap`

An `Effect<MemoMap>` that constructs a fresh, empty `MemoMap` within an effect.
Use it as the memoization root for a batch of `buildWithMemoMap` calls that
should share construction.

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

const program = Effect.gen(function*() {
  const memoMap = yield* Layer.makeMemoMap
  // => MemoMap (empty; pass to buildWithMemoMap)
  return memoMap
})
```

### `Layer.makeMemoMapUnsafe()`

The synchronous constructor for a `MemoMap` — returns the value directly,
outside of an effect. Handy when wiring up a runtime imperatively at the program
boundary.

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

const memoMap = Layer.makeMemoMapUnsafe()
// => MemoMap (empty, created synchronously)
```

### `Layer.forkMemoMap(parent)`

An `Effect<MemoMap>` that constructs a **child** `MemoMap`. The child can reuse
layers already memoized in `parent`, but layers it builds itself are isolated —
they are not written back to the parent. Use it when a sub-build should inherit
shared singletons without polluting the parent map.

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

const program = Effect.gen(function*() {
  const root = yield* Layer.makeMemoMap
  const child = yield* Layer.forkMemoMap(root)
  // => MemoMap that reads from `root` but isolates its own allocations
  return child
})
```

### `Layer.forkMemoMapUnsafe(parent)`

The synchronous variant of `forkMemoMap`: builds a child `MemoMap` from a parent
without an effect.

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

const root = Layer.makeMemoMapUnsafe()
const child = Layer.forkMemoMapUnsafe(root)
// => MemoMap (child of `root`, created synchronously)
```

### `Layer.CurrentMemoMap`

A `Context.Service` wrapping the `MemoMap` currently in use during layer
construction. `Layer.build` and friends read it from the fiber context (falling
back to a fresh one via `CurrentMemoMap.getOrCreate`). You rarely touch it
directly — it exists so custom layer operators can find the active memo map.

```ts
import { Context, Effect, Layer } from "effect"

const program = Effect.gen(function*() {
  // Reuse the active memo map (or create one) for a manual build.
  const memoMap = Layer.CurrentMemoMap.getOrCreate(
    yield* Effect.context<never>()
  )
  // => MemoMap currently associated with this fiber
  return memoMap
})
```

### `Layer.isLayer(value)`

A type guard that returns `true` when a value is a `Layer`. Useful in generic
code that accepts either a layer or something else.

```ts
import { Context, Effect, Layer } from "effect"

class Logger extends Context.Service<Logger, {
  readonly log: (msg: string) => Effect.Effect<void>
}>()("Logger") {}

const LoggerLive = Layer.succeed(Logger, {
  log: (msg) => Effect.sync(() => console.log(msg))
})

Layer.isLayer(LoggerLive) // => true
Layer.isLayer({ notALayer: true }) // => false
```

## Relationship to ManagedRuntime

These three layers of API are the same machinery at different altitudes:

- **`Layer.buildWithMemoMap` / `buildWithScope` / `build`** materialize a layer
  into a `Context` you can read services out of, given a `Scope` (and a
  `MemoMap` for sharing).
- **[`ManagedRuntime`](https://effect.plants.sh/services-and-layers/managed-runtime/)** wraps `build`
  together with its own `MemoMap` and `Scope`, giving you a reusable `Runtime`
  you can run many effects against and `dispose()` once — the natural choice for
  embedding Effect inside a non-Effect host (a CLI command, a test harness, a
  React app).
- **`Layer.launch`** is the thinnest wrapper of all: it `build`s the layer and
  then holds the scope open with `Effect.never`, so the application keeps running
  until interrupted. It is the right entrypoint when the layer *is* the whole
  app.

Pick `launch` for an app that runs until stopped, `ManagedRuntime` when you need
to drive Effect from the outside world, and the raw `build` APIs only when you
need the `Context` directly.