npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

effect-analyzer

v0.1.10

Published

Static analysis for Effect-TS code. Analyze Effect code to extract structure, calculate complexity, and generate visualizations.

Readme

effect-analyzer

Static analysis for Effect programs. Visualize service dependencies, error channels, concurrency, and control flow as Mermaid diagrams - without running your code.

Documentation · Getting Started · Playground · CLI Reference · API Reference

Why

Effect programs are powerful, but their structure - service dependencies, error topology, concurrency patterns - is hard to see in source. effect-analyzer parses your code with ts-morph and the TypeScript type checker, then produces semantic diagrams and structured analysis. No runtime, no instrumentation.

Use it for code review, onboarding, architecture docs, and CI to catch regressions in program shape.

Install

npm install -D effect-analyzer

effect (>=3.0.0) is a required peer dependency. ts-morph is bundled automatically.

Quick Start

# Auto-select the best diagrams for a file
npx effect-analyze ./src/transfer.ts

# Railway diagram (linear happy path with error branches)
npx effect-analyze ./src/transfer.ts --format mermaid-railway

# Plain-English explanation of what a program does
npx effect-analyze ./src/transfer.ts --format explain

# Compare two versions
npx effect-analyze HEAD:src/transfer.ts src/transfer.ts --diff

# Audit an entire project
npx effect-analyze ./src --coverage-audit

What You Get

Given an Effect program like this:

export const transfer = Effect.gen(function* () {
  const repo = yield* AccountRepo
  const audit = yield* AuditLog

  const balance = yield* repo.getBalance("from-account")

  if (balance < 100) {
    yield* Effect.fail(new InsufficientFundsError(balance, 100))
  }

  yield* repo.debit("from-account", 100)
  yield* repo.credit("to-account", 100)
  yield* audit.record("transfer-complete")
})

The analyzer produces a railway diagram showing the happy path with error branches:

flowchart LR
  A["repo <- AccountRepo"] -->|ok| B["audit <- AuditLog"]
  B -->|ok| C["balance <- repo.getBalance"]
  C -->|ok| D{"balance < 100"}
  D -->|ok| E["repo.debit"]
  E -->|ok| F["repo.credit"]
  F -->|ok| G["audit.record"]
  G -->|ok| Done((Success))
  C -.->|err| Err1([AccountNotFound])
  D -.->|err| Err2([InsufficientFunds])

Or a flowchart showing all control flow paths:

flowchart TB
  start((Start))
  n2["repo <- AccountRepo"]
  n3["audit <- AuditLog"]
  n4["balance <- repo.getBalance"]
  decision{"balance < 100?"}
  n7["Effect.fail(InsufficientFunds)"]
  n8["repo.debit"]
  n9["repo.credit"]
  n10["audit.record"]
  end_node((Done))

  start --> n2 --> n3 --> n4 --> decision
  decision -->|yes| n7
  decision -->|no| n8
  n7 -.-> end_node
  n8 --> n9 --> n10 --> end_node

Features

15+ Diagram Types

Auto-mode picks the most relevant views for your program, or choose explicitly:

| Format | Shows | |--------|-------| | mermaid-railway | Linear happy path with error branches | | mermaid | Full flowchart with all control flow | | mermaid-services | Service dependency map | | mermaid-errors | Error propagation and handling | | mermaid-concurrency | Parallel and race patterns | | mermaid-layers | Layer composition graph | | mermaid-retry | Retry and timeout strategies | | mermaid-timeline | Step sequence over time |

See all formats →

Complexity Metrics

Six metrics calculated for every program: cyclomatic complexity, cognitive complexity, path count, nesting depth, parallel breadth, and decision points.

npx effect-analyze ./src/transfer.ts --format stats

Learn more →

Semantic Diff

Compare two versions of a program at the structural level - not text diffs, but changes in steps, services, and control flow:

npx effect-analyze HEAD:src/transfer.ts src/transfer.ts --diff

Learn more →

Coverage Audit

Scan an entire project to understand Effect usage, identify complex programs, and track analysis quality:

npx effect-analyze ./src --coverage-audit

Learn more →

Interactive HTML Viewer

Generate a self-contained HTML page with search, filtering, path explorer, complexity heatmap, and 6 color themes:

import { renderInteractiveHTML } from "effect-analyzer"

const html = renderInteractiveHTML(ir, { theme: "midnight" })

Learn more →

Library API

Use the programmatic API to integrate analysis into your own tools:

import { analyze } from "effect-analyzer"
import { Effect } from "effect"

const ir = await Effect.runPromise(analyze("./src/transfer.ts").single())

console.log(ir.root.programName)    // "transfer"
console.log(ir.root.dependencies)    // [{ name: "AccountRepo", ... }, ...]
console.log(ir.root.errorTypes)      // ["InsufficientFundsError", "AccountNotFoundError"]

Full API reference →

What It Detects

| Area | Patterns | |------|----------| | Programs | Effect.gen, pipe chains, Effect.sync, Effect.async, Effect.promise | | Services | Context.Tag via yield*, service method calls | | Layers | Layer.mergeAll, Layer.effect, Layer.provide, Layer.succeed | | Errors | catchTag, catchAll, tapError, retry, timeout | | Concurrency | Effect.all, Effect.race, Effect.fork, Fiber.join | | Resources | acquireRelease, ensuring, Effect.scoped | | Streams | Stream.fromIterable, Stream.mapEffect, Stream.runCollect | | Control flow | if/else, for..of, while, try/catch, switch inside generators | | Schedules | Schedule.recurs, Schedule.exponential | | Aliases | const E = Effect, destructured imports, renamed imports |

Requirements

  • Node.js 22+
  • TypeScript project with effect (>=3.0.0)

Documentation

Full documentation is available at jagreehal.github.io/effect-analyzer.

License

MIT