> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Effect-TS/tsgo/llms.txt
> Use this file to discover all available pages before exploring further.

# Layer graph

> Visualise Layer dependency graphs as Mermaid diagrams in editor hover popups, and auto-compose layers with the layerMagic refactor.

The Effect Language Service extracts the dependency graph of any `Layer` value at your cursor and renders it as a [Mermaid](https://mermaid.js.org) flowchart inside the editor's hover popup. This makes it easy to understand which services a layer provides and which it requires, without reading through nested `Layer.provide` calls.

## What you see on hover

When you hover over any identifier or expression whose type is `Layer.Layer<ROut, E, RIn>`, the hover popup shows:

1. **A Mermaid flowchart** — nodes represent individual layer values; edges show dependency relationships. Each node is labelled with its source text plus the services it provides and requires.
2. **An external diagram link** — a URL to your configured Mermaid rendering service (e.g., mermaid.live) so you can open the full interactive diagram in a browser.
3. **Provider/requirer annotations** — a JSDoc-style block listing each service, where it is provided, and where it is required, including cross-file locations when applicable.

```
/**
 * - Database provided at ln 12 col 0 by `DatabaseLayer`
 * - Cache provided at ln 8 col 0 by `CacheLayer`
 *
 * - Http requires Database at ln 18 col 0 by `HttpLayer`
 * - Http requires Cache at ln 18 col 0 by `HttpLayer`
 */
```

The Mermaid diagram itself looks like this:

```
flowchart TD
  0["DatabaseLayer\nprovides: Database\nrequires: "]
  1["CacheLayer\nprovides: Cache\nrequires: "]
  2["HttpLayer\nprovides: Http\nrequires: Database, Cache"]
  0 -->|"provide"| 2
  1 -->|"provide"| 2
```

## Configuration

Layer graph behaviour is controlled by three plugin options in `tsconfig.json`.

### `mermaidProvider`

Controls which service is used to render the external Mermaid diagram link included in the hover popup.

| Value                      | URL prefix                                                                   |
| -------------------------- | ---------------------------------------------------------------------------- |
| `"mermaid.live"` (default) | `https://mermaid.live/edit#pako:…`                                           |
| `"mermaid.com"`            | `https://www.mermaid.com/edit#pako:…`                                        |
| Custom URL                 | Any string — used verbatim as the base URL prefix before the encoded diagram |

The diagram is encoded as a pako-compressed, base64url-encoded JSON payload (`{"code": "<diagram>"}`) appended to the base URL with the `pako:` prefix.

```jsonc theme={null}
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@effect/language-service",
        "mermaidProvider": "mermaid.live"
      }
    ]
  }
}
```

### `noExternal`

When `true`, suppresses the external Mermaid link from the hover popup. Only the inline diagram text and the provider/requirer annotations are shown. Useful in air-gapped environments or when you do not want clickable URLs in hover output.

```jsonc theme={null}
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@effect/language-service",
        "noExternal": true
      }
    ]
  }
}
```

**Default:** `false`

### `layerGraphFollowDepth`

Controls how many levels deep the layer graph extraction follows symbol references. At depth `0` (the default), the extractor only expands the layer expression at the cursor. At depth `1`, it also follows one level of symbol references (e.g., if `AppLayer` references `DatabaseLayer` by name, it resolves `DatabaseLayer` and includes its structure). Higher values follow more levels transitively.

```jsonc theme={null}
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@effect/language-service",
        "layerGraphFollowDepth": 1
      }
    ]
  }
}
```

**Default:** `0`

<Tip>
  Increase `layerGraphFollowDepth` when your layers are composed across multiple files and you want the hover to show the full transitive graph rather than just the top-level structure.
</Tip>

***

## Graph formats

The language service produces three internal graph representations, each rendered into the hover popup:

<AccordionGroup>
  <Accordion title="Flat graph (FormatLayerGraph)">
    A `flowchart TD` where each node is a single layer value with its source text, provides list, and requires list as a multi-line label. Cross-file nodes include a location annotation (`in filename.ts at ln N col N`). Edges are labelled with the relationship kind (e.g., `provide`, `merge`).

    ```
    flowchart TD
      0["DatabaseLayer\nprovides: Database\nrequires: Config"]
      1["ConfigLayer\nprovides: Config\nrequires: "]
      1 -->|"provide"| 0
    ```
  </Accordion>

  <Accordion title="Nested graph (FormatNestedLayerGraph)">
    A `flowchart TB` where each node is rendered as a nested subgraph with separate **Provides** and **Requires** subgraphs inside it. Edges connect matching type nodes between layers using dashed arrows, making it easy to see exactly which type satisfies which requirement.

    ```
    flowchart TB
      subgraph 0 ["`DatabaseLayer<br/><small>_ln 5 col 0_</small>`"]
        subgraph 0_requires [Requires]
          0_requires_0["Config"]
        end
        subgraph 0_provides [Provides]
          0_provides_0["Database"]
        end
      end
      0_requires_0 -.-> 1_provides_0
    ```
  </Accordion>

  <Accordion title="Outline graph (FormatOutlineGraph)">
    A simplified `flowchart TD` showing only the high-level dependency structure between named layer symbols, without internal type details. This is the form used by the `layerMagic` refactor to determine composition order.

    ```
    flowchart TD
      0["DatabaseLayer"]
      1["HttpLayer"]
      0 --> 1
    ```
  </Accordion>
</AccordionGroup>

***

## The `layerMagic` refactor

The layer graph powers the `layerMagic` refactor, which automatically composes a set of layers into the correct `Layer.provide` / `Layer.merge` / `Layer.provideMerge` pipeline.

See [Refactors → layerMagic](/features/refactors#layer-composition) for the full two-step workflow.

### How composition is determined

The outline graph is used to compute a topological sort of the layer nodes:

* A layer node that **provides** a service required by another node is placed earlier in the pipeline.
* When a node both provides a new service **and** satisfies a requirement of a downstream node, `Layer.provideMerge` is used.
* When a node only merges outputs without satisfying a downstream requirement, `Layer.merge` is used.
* When a node purely provides requirements for a downstream node, `Layer.provide` is used.

If the graph contains types that cannot be matched to any available layer, the refactor inserts a trailing comment listing the missing output types so you know what still needs to be provided.

```typescript theme={null}
const AppLayer = DatabaseLayer.pipe(
  Layer.provideMerge(CacheLayer),
  Layer.provide(HttpLayer)
  /* Unable to find Logger in the provided layers. */
)
```

***

## Full example

Given these layer definitions:

```typescript theme={null}
import { Layer, Effect } from "effect"

class Config extends Effect.Service<Config>()("Config", {
  effect: Effect.succeed({ port: 3000 })
}) {}

class Database extends Effect.Service<Database>()("Database", {
  dependencies: [Config],
  effect: Effect.gen(function* () {
    const config = yield* Config
    return { query: (sql: string) => Effect.succeed([]) }
  })
}) {}

class Http extends Effect.Service<Http>()("Http", {
  dependencies: [Database],
  effect: Effect.gen(function* () {
    const db = yield* Database
    return { get: (path: string) => db.query(`SELECT * FROM routes WHERE path = '${path}'`) }
  })
}) {}

// Hovering over AppLayer shows the full dependency graph
const AppLayer = Http.Default.pipe(
  Layer.provide(Database.Default),
  Layer.provide(Config.Default)
)
```

Hovering over `AppLayer` renders a Mermaid flowchart with three nodes and the correct dependency edges, plus a link to view the interactive diagram on mermaid.live.
