GitHub - Fcmam5/nx-mermaid-grapher: Create Mermaid graphs for NX dependencies

9 min read Original article ↗

Mutation testing badge Known Vulnerabilities codecov npm

A CLI and library to convert Nx dependency graphs into compact, human-readable formats — Mermaid, Graphviz DOT, JSON, plain-text edges, and workspace stats. Built for PR descriptions, documentation, and AI agent prompts.

Tip

Using this from an AI coding agent? nx-mermaid-grapher is designed to be a token-cheap window into an Nx workspace. Instead of feeding the model the full nx graph JSON (often tens to hundreds of kB), have the agent shell out to this CLI with --format edges or --format json to get a compact view of the dependency topology. The default mermaid output is great for showing the result back to the user — it renders natively in GitHub/GitLab markdown and in VS Code-based editors (Cursor, Windsurf, VSCodium, ...) with a Mermaid preview extension. See Output formats below for the short version, or the Usage guide for a full walkthrough of every format with realistic examples.

Table of Contents

Example

We can use this example project to try it out.

If you clone the project, and run nx dep-graph (or nx graph) we'd get something similar to:

Example Dep graph

And below is the generated mermaid.js graph (you can use controllers!):

    graph LR
      shared-infrastructure-nestjs-cqrs-events --> shared-domain
      lending-infrastructure --> lending-application
      lending-infrastructure --> shared-infrastructure-nestjs-cqrs-events
      lending-infrastructure --> lending-domain
      lending-infrastructure --> shared-domain
      lending-application --> lending-domain
      lending-application --> shared-domain
      lending-application --> catalogue
      lending-ui-rest --> lending-application
      lending-ui-rest --> lending-domain
      lending-ui-rest --> lending-infrastructure
      lending-domain --> shared-domain
      catalogue --> shared-domain
      catalogue --> shared-infrastructure-nestjs-cqrs-events
      library --> catalogue
      library --> lending-ui-rest
      library --> lending-domain
      library --> lending-infrastructure
Loading

Markdown:

```mermaid
    graph LR
        shared-infrastructure-nestjs-cqrs-events --> shared-domain
        lending-infrastructure --> lending-application
        lending-infrastructure --> shared-infrastructure-nestjs-cqrs-events
        lending-infrastructure --> lending-domain
        lending-infrastructure --> shared-domain
        lending-application --> lending-domain
        lending-application --> shared-domain
        lending-application --> catalogue
        lending-ui-rest --> lending-application
        lending-ui-rest --> lending-domain
        lending-ui-rest --> lending-infrastructure
        lending-domain --> shared-domain
        catalogue --> shared-domain
        catalogue --> shared-infrastructure-nestjs-cqrs-events
        library --> catalogue
        library --> lending-ui-rest
        library --> lending-domain
        library --> lending-infrastructure
```

Usage

CLI

To run this tool from your CLI, you need to install it globally with:

npm i -g nx-mermaid-grapher


# or using npx
npx nx-mermaid-grapher -f file.json

Then, run it with -f [PATH] or --file [PATH] parameter providing the path for your NX graph JSON output file.

Usage: nx-mermaid-grapher (-f <path> | --stdin) [-o <format>] [-e <lib>]... [-p <lib>]... [-t] [--raw]

Options:
  -f, --file <path>      NX graph output file. Pass `-` to read from stdin
                         (see: https://nx.dev/packages/nx/documents/dep-graph#file)
      --stdin            Read the graph JSON from stdin (alias for `-f -`)
  -o, --format <format>  Output format (default: mermaid).
                         One of: mermaid, edges, json, dot, stats
  -e, --exclude <lib>    Exclude a library (repeatable)
  -p, --projects <lib>   Include only these libraries (repeatable).
                         Useful for rendering affected-project subgraphs.
  -t, --transitive       When used with --projects, include the full transitive
                         closure in both directions. Forward traversal starts
                         from root seeds only to avoid unrelated siblings.
      --raw              Emit raw Mermaid (no ```mermaid markdown fence)
  -h, --help             Show help
  -V, --version          Show version

Example:

npx nx-mermaid-grapher -f tests/mocks/ddd-example.graph.json

Optionally you can exclude one, or multiple libraries. For example:

npx nx-mermaid-grapher -f tests/mocks/ddd-example.graph.json -e lending-infrastructure -e lending-ui-rest

Or skip the temp file entirely and pipe nx graph's output straight in:

nx graph --file=/dev/stdout | npx nx-mermaid-grapher --stdin -o stats
# (or the idiomatic form: `... | npx nx-mermaid-grapher -f -`)

Output formats

Pass -o <format> (or --format) to switch the output. The default is mermaid; the others exist so scripts and AI agents can consume the topology cheaply without re-parsing the much larger raw Nx graph JSON. Concretely, on the bundled DDD example fixture:

Output Size
raw nx graph JSON ~49,500 B
-o mermaid (default) ~770 B
-o json ~935 B
-o edges ~640 B
-o stats ~730 B

The exact ratio depends on the workspace, but the trend is the same: the raw graph carries per-project metadata (files, targets, tags, …) that this tool strips down to just the topology.

Format Use case
mermaid Paste into a Markdown doc, PR description, GitHub/GitLab README, or a chat reply. Renders natively on GitHub/GitLab and in VS Code-based editors (Cursor, Windsurf, VSCodium, …) with a Mermaid preview extension. Wrapped in a \``mermaid` fence by default.
edges One source target pair per line. Minimal whitespace, easy to awk/grep/feed to an LLM.
json Compact { "nodes": [...], "edges": [[src, dst], ...] }. Includes isolated nodes.
dot Graphviz digraph declaration; pipe into dot -Tsvg to render an image.
stats Plain-text summary: counts, roots/leaves, cycle flag, max depth + example longest path, per-project fan-in/fan-out. Single token-cheap snapshot of workspace shape.

Examples:

# Raw Mermaid body (no markdown fence) — handy when piping into a templater.
npx nx-mermaid-grapher -f graph.json --raw

# Plain edge list — the cheapest format for an AI agent to reason about.
npx nx-mermaid-grapher -f graph.json -o edges

# Compact JSON.
npx nx-mermaid-grapher -f graph.json -o json

# Graphviz, rendered to SVG.
npx nx-mermaid-grapher -f graph.json -o dot | dot -Tsvg > graph.svg

# One-shot summary (counts, roots/leaves, cycle check, hottest projects).
npx nx-mermaid-grapher -f graph.json -o stats

Tip

For AI agents and tool authors. Pick the format that matches what the model actually needs:

  • One-shot orientation ("how big is this workspace?", "any cycles?", "what are the load-bearing libs?") → use --format stats. A single block of text covers counts, roots/leaves, cycle detection, max depth, and per-project fan-in/fan-out.
  • Reasoning about structure ("which libs depend on auth?", "show me the path from library to shared-domain") → use --format edges or --format json. Both are much smaller than the raw Nx graph and have predictable shapes the model can parse without hallucinating fields.
  • Showing the user the topology in a chat reply, a PR comment, or a markdown report → use the default mermaid output. It renders natively on GitHub/GitLab and in VS Code-based editors (Cursor, Windsurf, VSCodium, …) with a Mermaid preview extension.
  • Producing an image for a doc site or a Slack message → use --format dot | dot -Tsvg (or -Tpng).

Combine with -e <lib> to drop noisy projects from the rendered subset before passing it to the model — fewer tokens, less distraction.

For a full walkthrough of every format with realistic outputs, recipes for querying the edge list with awk, and a programmatic-API example, see the Usage guide.

Code

If you want to extend this library, you may want to instantiate the exposed classes and use them, for example:

import { DiGraph, NXGraphFileLoader, NxMermaidGrapher } from 'nx-mermaid-grapher';

const loader = new NXGraphFileLoader();
const diGraph = new DiGraph();
const core = new NxMermaidGrapher(loader, diGraph);

core.init('path/to/file');

const logMerMaidInMd = (str: string) => `\`\`\`mermaid\n${str}\`\`\``;

console.log(logMerMaidInMd(core.getGraphSnippet()));

Or, if you wish to use a different graph than the default DiGraph (Directed graph), you may implement the IGraph<T> class and implement your own methods, for example:

import { IGraph } from "nx-mermaid-grapher/dist/data-structures/graph.ds.interface";

class SomeGraph implements IGraph<MyType> {
    addNode(nodeVal: MyType): void {
        throw new Error("Method not implemented.");
    }
    addEdge(source: MyType, destination: MyType): void {
        throw new Error("Method not implemented.");
    }
    getGraph(): { [key: string]: MyType[]; } {
        throw new Error("Method not implemented.");
    }
}

Then just pass it to NxMermaidGrapher constructor.

import {  NXGraphFileLoader, NxMermaidGrapher } from 'nx-mermaid-grapher';

const loader = new NXGraphFileLoader();
const myGraph = new SomeGraph();
const core = new NxMermaidGrapher(loader, myGraph);

Recipes

Render only the libs affected by a PR

Note: nx graph --affected --file=affected.json does not produce a JSON dump that contains only the affected projects. It outputs the full workspace graph (the --affected flag was historically used for the browser UI only). The affectedProjects field in the JSON was deprecated and removed in Nx 19.1.1 (see nrwl/nx#26501).

To get an actual affected-only subgraph, combine the two commands below:

# 1. Dump the *full* workspace graph (once).
npx nx graph --file=graph.json

# 2. Get the names of affected projects and render with impact context.
#    -t includes the full transitive closure around the affected set.
#    Requires `jq`; adjust --base to your target branch.
npx nx-mermaid-grapher -f graph.json -t \
  $(npx nx show projects --affected --json --base=origin/develop \
    | jq -r '.[] | "-p " + .')

You can swap --base=origin/develop for origin/main (or any commit-ish) and still combine with -e <lib> to hide noisy projects. Omit --transitive if you only want the strictly affected projects with no surrounding context.

Auto-post the affected graph as a PR comment (GitHub Actions)

Drop the workflow below at .github/workflows/affected-graph.yaml to have a fresh dependency-impact diagram appear on every pull request:

name: Affected dep graph

on:
  pull_request:
    branches: [develop, main]

permissions:
  contents: read
  pull-requests: write

jobs:
  graph:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          # Required so `--base=origin/${{ github.base_ref }}` has history.
          fetch-depth: 0

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - run: npm ci

      - name: Generate affected Mermaid graph
        run: |
          # 1. Dump the full workspace graph.
          npx nx graph --file=graph.json

          # 2. Get affected project names and build -p flags.
          PROJECTS=$(npx nx show projects --affected --json --base=origin/${{ github.base_ref }} | jq -r '.[] | "-p " + .' | xargs)

          # 3. Render the subgraph with impact context.
          {
            echo '## Affected dependency graph'
            echo
            npx nx-mermaid-grapher -f graph.json -t $PROJECTS
          } > graph.md

      - name: Comment on the PR
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: gh pr comment "${{ github.event.pull_request.number }}" --body-file graph.md

This posts a new comment on each push. If you would rather update a single sticky comment in place, swap the last step for an action like peter-evans/create-or-update-comment.

Project documents

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate. See CONTRIBUTING.md for development setup and the Code of Conduct.

License

This project is licensed under the MIT License - see the LICENSE file for details