# A Layer as constructor

> For agents: start with the [agent guide](https://ratstack.sh/llms.txt). Every page is Markdown by default; add `Accept: text/html` for HTML.

New on /news: [Effect Office Hours 52 with Resonate HQ](/news).

**Goal:** write a [Layer](/lore/layers-make-dependencies-explicit) the way you would write a class constructor.

A Layer describes how to build a [service](/lore/services-capture-dependencies) and supply its dependencies.
A service is the named [interface](/lore/one-schema-three-surfaces) callers use for a job.

## Worked example: a journal with private state

`FlagJournal` records flag changes.
Its `memory` Layer is a constructor:

packages/core/src/flag-journal.ts at a3f5a14861ce89913e82bea0f7ba02c83e8d4725; lines 34-41; highlighted 38,40. Title: Ref.make is a field; FlagJournal.of is the method table.

```typescript
>()("@rat-stack/core/FlagJournal") {
  static memory = Layer.effect(
    FlagJournal,
    Effect.gen(function* makeFlagJournal() {
      const entries = yield* Ref.make<readonly FlagChange[]>([]);

      return FlagJournal.of({
        list: Effect.fn("FlagJournal.list")(function* list(input) {
```

Read it as a class:

- `Layer.effect(FlagJournal, …)` is the constructor for `FlagJournal`.
- `Ref.make([])` creates a private field. Only the returned methods can reach `entries`.
- `FlagJournal.of({ … })` returns the methods, checked against the service interface.

Each build of the Layer runs the constructor once and creates a fresh `entries` list.

## One service, two constructors

A class can have more than one constructor. A service can have more than one Layer.
`Drift` checks pinned code excerpts against the current source:

packages/code-snippets/src/drift.ts at a3f5a14861ce89913e82bea0f7ba02c83e8d4725; lines 23-31; highlighted 24,28,31. Title: silent needs nothing; layer needs SourceRepository.

```typescript
>()("code-snippets/Drift") {
  static readonly silent = Layer.succeed(
    Drift,
    Drift.of({ check: () => Effect.succeed([]) })
  );
  static readonly layer = Layer.effect(
    Drift,
    Effect.gen(function* makeDrift() {
      const repository = yield* SourceRepository;
```

- `Drift.silent` uses `Layer.succeed`. It needs nothing and reports nothing.
- `Drift.layer` uses `Layer.effect`. Its constructor asks for `SourceRepository`, so the Layer carries that [requirement](/lore/effect-basics).

Callers ask for `Drift` either way. The [composition root](/lore/structure-effect-by-domain) picks the constructor.

## Why it matters

A constructor argument becomes a Layer requirement. The type shows it, and the root must supply it.

Sam compares the constructor pattern to a Layer and uses a React component as an analogy. In the same discussion, he connects the pattern to infrastructure policies. [Watch from 18:45](https://youtu.be/MtKHzAH6uXM?t=1125)

## Next

Read [Layers make dependencies explicit](/lore/layers-make-dependencies-explicit) to compose several Layers.
Then read [why dependency injection matters](/lore/dependency-injection-is-the-reason-to-choose-effect).

See [Sam Goodwin on Alchemy](/lore/devtools-fm-sam-goodwin-alchemy) and [cartridges](/lore/cartridges).

## Sources

1. [Sam Goodwin - Alchemy - YouTube](https://youtu.be/MtKHzAH6uXM?t=1125)
   Sam Goodwin. Layer composition discussion; used for infrastructure carried with a service. Accessed 2026-10-01.

2. [Flag journal service](https://github.com/joelhooks/rat-stack/blob/a3f5a14861ce89913e82bea0f7ba02c83e8d4725/packages/core/src/flag-journal.ts)
   GitHub joelhooks/rat-stack. FlagJournal.memory builds private state with Ref.make and returns methods with FlagJournal.of. Accessed 2026-11-08.

3. [Source drift service](https://github.com/joelhooks/rat-stack/blob/a3f5a14861ce89913e82bea0f7ba02c83e8d4725/packages/code-snippets/src/drift.ts)
   GitHub joelhooks/rat-stack. Drift has two Layers: silent needs nothing, and layer needs SourceRepository. Accessed 2026-11-08.

## Linked from

- A service captures its construction dependencies → Build a service with its dependencies, then expose methods that callers can use without rebuilding the graph. → [Read page](https://ratstack.sh/lore/services-capture-dependencies)

- Agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms.txt)

- Change log → What changed in the files served here, newest first. → [Read page](https://ratstack.sh/log)

- Code snippets quote a pinned source → Shipped design brief: pinned Git objects, typed diagnostics, and one build-only snippet model for both views. → [Read page](https://ratstack.sh/lore/code-snippets)

- Dependency injection is the reason to choose Effect → Effect tracks service requirements in types and supplies replaceable implementations through Layers. → [Read page](https://ratstack.sh/lore/dependency-injection-is-the-reason-to-choose-effect)

- Engine-neutral tokens keep adapters replaceable → The highlighter port exposes text, roles, and font styles rather than Shiki types. → [Read page](https://ratstack.sh/lore/engine-neutral-tokens-keep-adapters-replaceable)

- Full agent guide → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/llms-full.txt)

- Hexagonal architecture → Ports name the application's jobs; adapters connect them to the outside world. → [Read page](https://ratstack.sh/lore/hexagonal-architecture)

- learn-rat-stack → Trace a capability through Effect, XState, five projections, the CLI, and Alchemy. Try hosted search and read. → [Read page](https://ratstack.sh/skills/learn-rat-stack)

- Rat Stack lore | rat-stack → Short, source-grounded notes on the ideas and decisions behind rat-stack. → [Read page](https://ratstack.sh/lore)

- rat-stack → An Effect stack so pure (aspirational) Kit Langton will blush. → [Read page](https://ratstack.sh/)

- Source change history (log.md) → The generated change log as Markdown. → [Read page](https://ratstack.sh/log.md)
