Skip to content

Library API

All exports are available from the effect-analyzer package. The library is designed for integration into custom tools, CI pipelines, and editors.

import { analyze, renderMermaid, calculateComplexity } from "effect-analyzer"

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

import { analyze } from "effect-analyzer"
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"
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"
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):

MethodDescription
.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.

FunctionDescription
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"
import { Effect } from "effect"
const diagram = await Effect.runPromise(renderMermaid(ir, {
direction: "LR", // TB | LR | BT | RL
styleGuide: true, // Apply readability heuristics
}))
FunctionDescription
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"
const html = renderInteractiveHTML(ir, {
title: "Transfer Analysis",
theme: "midnight", // midnight | ocean | ember | forest | daylight | paper
})

See Interactive HTML for full details.

FunctionDescription
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"
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"
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"
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"
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"
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"
const result = lintEffectProgram(ir, DEFAULT_LINT_RULES)

Format lint issues as a human-readable report.

RuleDescription
errorTypeTooWideRuleError type is unknown or Error instead of a tagged union
unboundedParallelismRuleEffect.all without concurrency option
redundantPipeRuleSingle-step pipe that could be simplified
orDieWarningRuleUse of Effect.orDie which discards error info
untaggedYieldRuleYield without a descriptive variable name
missingErrorHandlerRuleErrors produced but no handler present
deadCodeRuleUnreachable code after terminal effects
complexLayerRuleLayer with too many dependencies
catchAllVsCatchTagRulecatchAll 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.

FunctionDescription
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/platform 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