Skip to main content

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.

The Effect Language Service extracts the dependency graph of any Layer value at your cursor and renders it as a Mermaid 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.
ValueURL prefix
"mermaid.live" (default)https://mermaid.live/edit#pako:…
"mermaid.com"https://www.mermaid.com/edit#pako:…
Custom URLAny 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.
{
  "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.
{
  "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.
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "@effect/language-service",
        "layerGraphFollowDepth": 1
      }
    ]
  }
}
Default: 0
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.

Graph formats

The language service produces three internal graph representations, each rendered into the hover popup:
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
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
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

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 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.
const AppLayer = DatabaseLayer.pipe(
  Layer.provideMerge(CacheLayer),
  Layer.provide(HttpLayer)
  /* Unable to find Logger in the provided layers. */
)

Full example

Given these layer definitions:
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.

Build docs developers (and LLMs) love