Skip to content

Library API

Effect v4 is the only supported Effect release. The small root interface covers the canonical analysis/fidelity/trace workflow; expert capabilities live under effect-analyzer/analysis, effect-analyzer/diagram, effect-analyzer/rules, and effect-analyzer/migration.

import { analyze, renderMermaid, calculateComplexity } from "effect-analyzer/diagram"
Import Use it for
effect-analyzer Analysis sessions, fidelity checks, trace adapters, runtime overlays
effect-analyzer/analysis Full static analysis, project audits, IR traversal, paths, and data flow
effect-analyzer/diagram Mermaid, HTML, JSON, summaries, and diagram quality
effect-analyzer/rules Source linting, strict diagnostics, and rule metadata
effect-analyzer/migration Migration findings and semantic diffs

The v4 release removes expert APIs from the root import. Move each old root import to the matching entry point above.

The root package exports a configured Node analysis session. It initializes ts-morph before you analyze a file, source string, or project.

import { analysis } from "effect-analyzer"
import { Effect } from "effect"
const one = await Effect.runPromise(analysis.file("./src/program.ts").single)
const fromSource = await Effect.runPromise(analysis.source(source).all)
const project = await Effect.runPromise(analysis.project("./src"))
const audit = await Effect.runPromise(analysis.audit("./src"))
analysis.clearCaches()

Call createAnalysisSession() when tests or tools need separate session objects. The sessions share the analyzer’s project cache until you call clearCaches().

The primary entry point. Returns a fluent API for extracting programs from a file.

import { analyze } from "effect-analyzer/analysis"
import { Effect } from "effect"
// Get a single program (throws if file has zero or multiple)
const ir = await Effect.runPromise(analyze("./src/program.ts").single)
// Get all programs in a file
const irs = await Effect.runPromise(analyze("./src/program.ts").all)
// Get a program by name
const named = await Effect.runPromise(analyze("./src/program.ts").named("transfer"))

Lower-level file analysis. Returns StaticEffectIR[] - one IR per detected program.

analyzeEffectSource(source, filePath?, options?)

Section titled “analyzeEffectSource(source, filePath?, options?)”

Analyze a TypeScript source string directly, without reading from disk:

import { analyzeEffectSource } from "effect-analyzer/analysis"
const irs = analyzeEffectSource(`
import { Effect } from 'effect';
export const hello = Effect.succeed('world');
`)

Analyze a TypeScript source string using the fluent API:

import { analyze } from "effect-analyzer/analysis"
import { Effect } from "effect"
const ir = await Effect.runPromise(analyze.source(`
import { Effect } from 'effect';
export const hello = Effect.succeed('world');
`).single)

The fluent API methods available on analyze(path) and analyze.source(code):

Method Description
.single Returns exactly one program (fails if zero or multiple)
.singleOption Returns Option<IR> - None if zero programs, fails if multiple
.all Returns all programs as an array
.named(name) Returns the program matching the given name
.first Returns the first program (fails if zero programs)
.firstOption Returns Option<IR> - the first program or None

Analyze all TypeScript files in a directory. Returns a ProjectAnalysisResult with per-file outcomes.

Run a coverage audit across a directory. Returns a CoverageAuditResult with named effectAdoption, analysisSuccess, and sourceResolution assessment dimensions. Each dimension contains { numerator, denominator, rate }.

Discover and analyze a project once. The returned Project corpus records every file and its Effect IR programs, zero-program result, analysis failure, and optional timing. Project-wide views use this shared evidence model.

Pass the corpus to analysis.projectFromCorpus(corpus) and analysis.auditFromCorpus(corpus) to derive both views without scanning source files again.

Evaluate native CI expectations against an Audit assessment. Returns a pass or fail decision with typed violations and does not mutate the measurements.

The analysis entry point exports one traversal vocabulary for the full IR tree. Traversal functions accept ir.root.children; the index accepts the full IR.

Function Result
childrenOf(node) Direct children for any supported IR node
visitIR(roots, visitor) Depth-first visit with parent and ancestor data
flattenIR(roots) All nodes in depth-first order
indexIR(ir) IDs, parents, runtime span paths, and span-path lookups
runtimeSpanNames(node) Literal span names attached to one node

The root package exports findStaticNodesForSpanPath(ir, path) for runtime-path lookups.

import { indexIR } from "effect-analyzer/analysis"
const index = indexIR(ir)
const parent = index.parentById.get(nodeId)
const spanPath = index.spanPathById.get(nodeId)

computeDiagramFidelity(ir) reports whether the IR can identify each diagram node without ambiguity. It reports unknown nodes, opaque nodes, computed span names, and duplicate span paths.

import {
computeDiagramFidelity,
formatDiagramFidelity,
} from "effect-analyzer"
const report = computeDiagramFidelity(ir)
console.log(formatDiagramFidelity(report))

Use traceFromEffectSpans() for Effect v4 spans or traceFromOpenTelemetry() for exported OpenTelemetry spans. renderMermaidWithRuntimeTrace() colors matched nodes by runtime status and returns unmatched or ambiguous span IDs.

import {
renderMermaidWithRuntimeTrace,
traceFromOpenTelemetry,
} from "effect-analyzer"
const trace = traceFromOpenTelemetry(readableSpans)
const result = renderMermaidWithRuntimeTrace(ir, trace)
console.log(result.mermaid)
console.log(result.unmatchedSpanIds)

Read Diagram Fidelity for span naming rules and CI usage.

Function Description
renderMermaid(ir, options?) Standard flowchart
renderStaticMermaid(ir, options?) Static flowchart (no animation)
renderRailwayMermaid(ir, options?) Railway diagram with error branches
renderPathsMermaid(ir, options?) All execution paths as separate flows
renderEnhancedMermaid(ir, options?) Rich annotations per node
renderServiceGraphMermaid(ir) Service dependency graph
renderSequenceMermaid(ir) Sequence diagram
renderRetryGanttMermaid(ir) Retry timeline as Gantt chart
renderGraphMermaid(graph) Cross-program composition graph
renderCompositionMermaid(graph) Composition with call edges
renderCompositionWithServicesMermaid(graph) Composition including service nodes

All Mermaid renderers accept a MermaidOptions object:

import { renderMermaid } from "effect-analyzer/diagram"
import { Effect } from "effect"
const diagram = await Effect.runPromise(renderMermaid(ir, {
direction: "LR", // TB | LR | BT | RL
styleGuide: true, // Apply readability heuristics
}))
Function Description
renderJSON(ir, options?) Full IR as JSON
renderMultipleJSON(irs) Multiple IRs as JSON array
renderExplanation(ir) Plain-English narrative
renderMultipleExplanations(irs) Explanations for multiple programs
renderSummary(ir) One-line summary
renderMultipleSummaries(irs) Summaries for multiple programs
renderDependencyMatrix(irs) Program-by-service dependency table
renderDocumentation(ir, options?) Markdown documentation
renderMultiProgramDocs(irs, options?) Documentation for multiple programs
generateShowcase(ir, options?) Detailed step-by-step showcase
import { renderInteractiveHTML } from "effect-analyzer/diagram"
const html = renderInteractiveHTML(ir, {
title: "Transfer Analysis",
theme: "midnight", // midnight | ocean | ember | forest | daylight | paper
})

See Interactive HTML for full details.

Function Description
renderApiDocsMarkdown(structure) HttpApi structure to markdown
renderApiDocsMermaid(structure) HttpApi structure to Mermaid
renderOpenApiPaths(structure) Minimal OpenAPI paths
extractHttpApiStructure(ir) Extract HttpApi info from IR

Returns ComplexityMetrics with 6 metrics:

import { calculateComplexity } from "effect-analyzer/analysis"
const metrics = calculateComplexity(ir)
// { cyclomaticComplexity, cognitiveComplexity, pathCount, maxDepth, maxParallelBreadth, decisionPoints }

Evaluate metrics against thresholds. Returns a ComplexityAssessment with severity and warnings.

Format metrics as a human-readable one-liner.

The default complexity thresholds object.

Enumerate execution paths. Returns EffectPath[].

import { generatePaths } from "effect-analyzer/analysis"
const paths = generatePaths(ir, { maxPaths: 100, expandLoops: true })

Same as generatePaths but returns a PathGenerationResult with a limitHit flag.

Aggregate statistics across paths.

Filter paths by step names, error conditions, or loop presence.

Generate test cases from paths. Returns a TestMatrix.

import { generateTestMatrix } from "effect-analyzer/analysis"
const matrix = generateTestMatrix(paths, { testNamePrefix: "should" })

Render the test matrix as a markdown table.

Generate test code skeletons for vitest, jest, or mocha.

Render the test matrix as a markdown checklist.

Build a data flow graph tracking value producers and consumers.

import { buildDataFlowGraph, getProducers, getConsumers } from "effect-analyzer/analysis"
const graph = buildDataFlowGraph(ir)
const producers = getProducers(graph, "AccountService")
const consumers = getConsumers(graph, "balance")

Topological order of data flow nodes.

All transitive dependencies of a node.

Detect circular dependencies in the data flow.

Check for undefined reads and duplicate writes.

Render the data flow graph as a Mermaid diagram.

Extract all error types and map them to steps.

Track how errors propagate through the program and how handlers narrow them.

Look up the error state at a specific node.

Find all steps that can produce a given error type.

Check for undeclared and unused error types.

Render the error flow as a Mermaid diagram.

Human-readable error summary.

Build a dependency graph of all layers in a set of IRs.

Render the layer graph as Mermaid.

Find circular layer dependencies.

Find diamond dependencies in the layer graph.

Find services that are required but have no layer provider.

Track service provisions, unsatisfied services, and lifecycle.

Build a project-wide map of all services, their providers, and consumers.

Compare two program IRs. Returns a structured diff.

Render the diff as markdown.

Render the diff as JSON.

Render the diff as a Mermaid diagram with change highlights.

Parse a ref:path string into its components.

Resolve a git ref to source code.

Build a call graph across multiple programs.

analyzeProjectComposition(dirPath, options?)

Section titled “analyzeProjectComposition(dirPath, options?)”

Analyze composition across an entire project.

Topological sort of the program call graph.

Get direct dependencies of a program.

Get direct dependents of a program.

Complexity metrics for the composition graph.

Validate an IR against strict diagnostic rules.

import { validateStrict } from "effect-analyzer/rules"
const result = validateStrict(ir, { warningsAsErrors: true })

Human-readable diagnostic output.

JSON diagnostic output.

Error and warning counts.

Build a cache of const declarations from a ts-morph source file.

Look up a const value by name.

Convert a ConstValue to a plain JavaScript value.

Extract a string array from a const or literal.

Extract a single string value.

Choose between 'mermaid' and 'railway' based on IR structure.

Select the full set of auto-mode formats for a program.

Run lint rules against an Effect program IR.

import { lintEffectProgram, DEFAULT_LINT_RULES } from "effect-analyzer/rules"
const result = lintEffectProgram(ir, DEFAULT_LINT_RULES)

Format lint issues as a human-readable report.

Rule Description
errorTypeTooWideRule Error type is unknown or Error instead of a tagged union
unboundedParallelismRule Effect.all without concurrency option
redundantPipeRule Single-step pipe that could be simplified
orDieWarningRule Use of Effect.orDie which discards error info
untaggedYieldRule Yield without a descriptive variable name
missingErrorHandlerRule Errors produced but no handler present
deadCodeRule Unreachable code after terminal effects
complexLayerRule Layer with too many dependencies
catchVsCatchTagRule catch used where catchTag would be more precise

Extract Effect<A, E, R> type parameters from a ts-morph node.

Extract Stream<A, E, R> type parameters.

Extract Layer<A, E, R> type parameters.

Get all service requirements for a program.

Format a type signature as a readable string.

Compute readability metrics for a program’s diagram.

Compute quality metrics for all programs in a file.

Build a report of the worst-quality diagrams.

Function Description
analyzeStateFlow(ir) Track Ref mutations and race conditions
analyzeScopeResource(ir) Analyze acquireRelease and scope boundaries
analyzeObservability(ir) Find spans, log points, and metrics
analyzeFiberLeaks(ir) Detect potentially leaked fibers
analyzeGenYields(ir) Detailed analysis of yield* bindings in generators
analyzeMatch(ir) Analyze Match pattern sites and arms
analyzePlatformUsage(ir) Detect Effect v4 platform-module usage
analyzeSqlPatterns(ir) Detect @effect/sql patterns
analyzeRpcPatterns(ir) Detect @effect/rpc patterns
analyzeRequestBatching(ir) Detect request batching patterns
analyzeStm(ir) Detect STM (software transactional memory) usage
analyzeConfig(ir) Analyze Config usage
analyzeTestingPatterns(ir) Detect testing patterns (TestContext, TestClock)
checkDICompleteness(irs) Check if all services have layer providers
formatDICompletenessReport(result) Format DI completeness check as a report
findMigrationOpportunities(path) Find patterns migratable to Effect
exportForPlayground(ir) Export IR for the Effect playground