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

diagram-sync

v3.7.0

Published

Automatically export diagrams from PlantUML, Mermaid, Graphviz, Draw.io, D2, Excalidraw, and BPMN source files — keeps architecture documentation in sync with code across CI/CD pipelines, npm scripts, and local workflows.

Readme

diagram-sync

Keep architecture diagrams synchronized with source code.

npm version npm downloads license coverage

diagram-sync is a CLI tool that automatically generates images from diagram source files. Drop it into any repo and run npx diagram-sync — it finds every supported diagram file, renders it to an image, and mirrors the output under a diagrams/ folder. No config required.

npx diagram-sync

demo


The Problem

Engineering teams update code but forget to re-export architecture diagrams. The result is stale documentation — READMEs, wikis, and onboarding docs that no longer reflect reality.

diagram-sync eliminates the manual export step entirely. You edit the diagram source file. It generates the image automatically — locally or in CI/CD.

Honest note: This tool removes export friction. It does not force developers to keep source diagrams accurate. That is a people problem, not a tooling problem.


Install

# one-off, no install required
npx diagram-sync

# or install globally
npm install -g diagram-sync

# or as a dev dependency
npm install --save-dev diagram-sync

Quick Start

  1. Add a supported diagram source file anywhere in your repo
  2. Run npx diagram-sync from the project root
  3. Find the generated image in diagrams/ mirroring the source path

| Source | Generated | | --- | --- | | docs/└── providers/ ├── plantuml/ │ └── system.puml └── mermaid/ └── auth.mmd | diagrams/└── docs/ └── providers/ ├── plantuml/ │ └── system.svg └── mermaid/ └── auth.svg |

Once committed, the generated images are plain files in your repository — embed them in READMEs, wikis, internal docs, or link to them from anywhere on the internet via their raw GitHub URL.


How It Works

  • Recursively scans your repo for diagram source files
  • Skips node_modules, .git, dist, build, diagrams
  • Derives the output path from the source file location — no input/output directories to configure
  • Generates images using the installed diagram tool for each provider — defaults to SVG, configurable via --format flag or config file

Supported Providers

diagram-sync supports any diagram source that is committed to Git, maintained as a file, and can be converted to an image via a CLI — regardless of whether it was created by hand, a GUI tool, or AI.

| Provider | Extensions | Guide | | --- | --- | --- | | PlantUML | .puml, .plantuml | Setup & CI/CD | | Mermaid | .mmd, .mermaid | Setup & CI/CD | | Graphviz | .dot, .gv | Setup & CI/CD | | Draw.io | .drawio, .dio | Setup & CI/CD | | D2 | .d2 | Setup & CI/CD | | Excalidraw | .excalidraw | Setup & CI/CD | | BPMN | .bpmn | Setup & CI/CD |


Usage Options

1. One-off local generation

npx diagram-sync

demo

2. npm script

"scripts": {
  "diagrams": "npx diagram-sync"
}
npm run diagrams

demo-npm

3. Regenerate specific files only

Pass explicit paths — skips discovery entirely. Used by CI to regenerate only the files changed in a push or PR.

npx diagram-sync --files docs/providers/d2/network.d2 docs/providers/plantuml/system.puml

demo-files

4. Regenerate only locally changed files

Processes only files modified since the last commit (git diff HEAD + untracked). Useful locally to avoid regenerating every diagram in a large repo.

npx diagram-sync --changed

demo-changed

Exit codes and output names

diagram-sync exits with code 1 if any diagram fails to render, including a missing provider tool or a source file that doesn't exist, so CI jobs fail instead of passing silently.

Each source path/to/name.ext is written to diagrams/path/to/name.<format>, whatever title the diagram declares (for example @startuml My Title). If two sources in one folder share a name, such as architecture.puml and architecture.excalidraw, they write the same file; diagram-sync warns about it, and you should rename one of them.

5. Config file

Config is optional — no config file needed to get started. Add diagram-sync.config.json to your project root to control formats per provider or scope which providers run.

{
  "format": "svg",
  "jobs": [
    {
      "name": "architecture",
      "type": "plantuml",
      "format": "png",
      "background": "#FFFFFF"
    },
    {
      "name": "flows",
      "type": "mermaid"
    }
  ]
}
npx diagram-sync --config diagram-sync.config.json

Override format at runtime without a config file:

npx diagram-sync --format svg

Format resolution order: --format flag → job format → global format → default svg.

demo-config

Job Options

| Field | Type | Description | | --- | --- | --- | | name | string | Label for the job (used in logs) | | type | string | Diagram provider (plantuml, mermaid, graphviz, drawio, d2, excalidraw, bpmn) | | format | string | Output format for this job (e.g. png, svg, pdf) — overrides global format | | background | string | Background color for PlantUML diagrams — defaults to #FFFFFF. Accepts hex codes or named colors (e.g. transparent, #F5F5F5) |

6. CI/CD

Generates a preview on every PR and commits images to main on merge.

Remove the install steps and path filters for providers you don't use — most teams only need 1–2.

name: Generate and Commit Diagrams

# Remove path entries for providers you don't use.
# The workflow only triggers when a matching source file changes.
on:
  pull_request:
    paths:
      # PlantUML — remove if not using .puml / .plantuml files
      - '**/*.puml'
      - '**/*.plantuml'
      # Mermaid — remove if not using .mmd / .mermaid files
      - '**/*.mmd'
      - '**/*.mermaid'
      # Graphviz — remove if not using .dot / .gv files
      - '**/*.dot'
      - '**/*.gv'
      # Draw.io — remove if not using .drawio / .dio files
      - '**/*.drawio'
      - '**/*.dio'
      # D2 — remove if not using .d2 files
      - '**/*.d2'
      # Excalidraw — remove if not using .excalidraw files
      - '**/*.excalidraw'
      # BPMN — remove if not using .bpmn files
      - '**/*.bpmn'
  push:
    branches: [main]
    paths:
      # PlantUML — remove if not using .puml / .plantuml files
      - '**/*.puml'
      - '**/*.plantuml'
      # Mermaid — remove if not using .mmd / .mermaid files
      - '**/*.mmd'
      - '**/*.mermaid'
      # Graphviz — remove if not using .dot / .gv files
      - '**/*.dot'
      - '**/*.gv'
      # Draw.io — remove if not using .drawio / .dio files
      - '**/*.drawio'
      - '**/*.dio'
      # D2 — remove if not using .d2 files
      - '**/*.d2'
      # Excalidraw — remove if not using .excalidraw files
      - '**/*.excalidraw'
      # BPMN — remove if not using .bpmn files
      - '**/*.bpmn'
  workflow_dispatch:

# Keep in sync with the providers you use. Paths are NUL-separated end to end
# (git diff -z | grep -z | xargs -0) so file names with spaces survive.
env:
  DIAGRAM_PATTERN: '\.(puml|plantuml|mmd|mermaid|dot|gv|drawio|dio|d2|excalidraw|bpmn)$'

jobs:
  preview:
    name: Generate Preview
    runs-on: ubuntu-latest
    if: github.event_name == 'pull_request'

    steps:
      - uses: actions/checkout@v5
        with:
          # Full history required so git diff can resolve the base ref.
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v5
        with:
          node-version: '20'

      # --- PlantUML — remove if not using .puml / .plantuml files ---
      # Graphviz is needed for every PlantUML diagram type except sequence diagrams.
      - name: Install PlantUML and Graphviz
        run: |
          sudo apt-get update -q
          sudo apt-get install -y --no-install-recommends default-jre-headless plantuml graphviz

      # --- Mermaid — remove if not using .mmd / .mermaid files ---
      - name: Install Mermaid CLI
        run: npm install -g @mermaid-js/mermaid-cli

      # --- Graphviz — remove if not using .dot / .gv files (already installed above if using PlantUML) ---
      - name: Install Graphviz
        run: |
          sudo apt-get update -q
          sudo apt-get install -y graphviz

      # --- Draw.io — remove if not using .drawio / .dio files ---
      - name: Install Draw.io
        run: |
          DRAWIO_VERSION=$(curl -s https://api.github.com/repos/jgraph/drawio-desktop/releases/latest | jq -r '.tag_name | ltrimstr("v")')
          wget -q "https://github.com/jgraph/drawio-desktop/releases/download/v${DRAWIO_VERSION}/drawio-amd64-${DRAWIO_VERSION}.deb" -O drawio.deb
          sudo apt-get install -y ./drawio.deb xvfb

      # --- D2 — remove if not using .d2 files ---
      - name: Install D2
        run: curl -fsSL https://d2lang.com/install.sh | sh

      # --- Excalidraw — remove if not using .excalidraw files ---
      - name: Install Excalidraw CLI
        run: npm install -g @swiftlysingh/excalidraw-cli

      # --- BPMN — remove if not using .bpmn files ---
      - name: Install BPMN CLI
        run: |
          npm install -g bpmn-to-image
          sed -i "s/headless: 'new'/headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox']/" $(npm root -g)/bpmn-to-image/index.js

      - name: Install diagram-sync
        run: npm install -g diagram-sync

      - name: Generate changed diagrams
        env:
          BASE_REF: ${{ github.base_ref }}
        run: |
          git diff -z --name-only --diff-filter=d "origin/${BASE_REF}...HEAD" \
            | { grep -zE "$DIAGRAM_PATTERN" || echo "No diagram files changed." >&2; } \
            | xargs -0 -r diagram-sync --files
        # add --format png or --format pdf after --files to override the default svg output

      # !cancelled() so previews of the diagrams that did render are still
      # uploaded when another one fails
      - name: Upload diagram previews
        if: ${{ !cancelled() }}
        uses: actions/upload-artifact@v4
        with:
          name: diagrams-preview
          path: diagrams/
          if-no-files-found: ignore

  commit:
    name: Generate and Commit
    runs-on: ubuntu-latest
    if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
    permissions:
      contents: write

    steps:
      - uses: actions/checkout@v5
        with:
          # GITHUB_TOKEN with contents: write is enough when main is unprotected.
          # If a branch ruleset blocks pushes from GITHUB_TOKEN, save a fine-grained PAT
          # (Contents: read+write) as PAT_TOKEN; it is used automatically when present.
          token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
          # Full history required so git diff can resolve the previous commit.
          fetch-depth: 0

      - name: Setup Node
        uses: actions/setup-node@v5
        with:
          node-version: '20'

      # --- PlantUML — remove if not using .puml / .plantuml files ---
      # Graphviz is needed for every PlantUML diagram type except sequence diagrams.
      - name: Install PlantUML and Graphviz
        run: |
          sudo apt-get update -q
          sudo apt-get install -y --no-install-recommends default-jre-headless plantuml graphviz

      # --- Mermaid — remove if not using .mmd / .mermaid files ---
      - name: Install Mermaid CLI
        run: npm install -g @mermaid-js/mermaid-cli

      # --- Graphviz — remove if not using .dot / .gv files (already installed above if using PlantUML) ---
      - name: Install Graphviz
        run: |
          sudo apt-get update -q
          sudo apt-get install -y graphviz

      # --- Draw.io — remove if not using .drawio / .dio files ---
      - name: Install Draw.io
        run: |
          DRAWIO_VERSION=$(curl -s https://api.github.com/repos/jgraph/drawio-desktop/releases/latest | jq -r '.tag_name | ltrimstr("v")')
          wget -q "https://github.com/jgraph/drawio-desktop/releases/download/v${DRAWIO_VERSION}/drawio-amd64-${DRAWIO_VERSION}.deb" -O drawio.deb
          sudo apt-get install -y ./drawio.deb xvfb

      # --- D2 — remove if not using .d2 files ---
      - name: Install D2
        run: curl -fsSL https://d2lang.com/install.sh | sh

      # --- Excalidraw — remove if not using .excalidraw files ---
      - name: Install Excalidraw CLI
        run: npm install -g @swiftlysingh/excalidraw-cli

      # --- BPMN — remove if not using .bpmn files ---
      - name: Install BPMN CLI
        run: |
          npm install -g bpmn-to-image
          sed -i "s/headless: 'new'/headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox']/" $(npm root -g)/bpmn-to-image/index.js

      - name: Install diagram-sync
        run: npm install -g diagram-sync

      # continue-on-error so one broken diagram doesn't stop the others from being
      # committed. The last step still fails the job if anything failed here.
      - name: Generate diagrams
        id: generate
        continue-on-error: true
        env:
          EVENT_NAME: ${{ github.event_name }}
          BEFORE_SHA: ${{ github.event.before }}
          AFTER_SHA: ${{ github.sha }}
        run: |
          # Regenerate everything on manual runs, or when there is no previous
          # commit to diff against (first push / new branch).
          if [ "$EVENT_NAME" = "workflow_dispatch" ] || [ -z "$BEFORE_SHA" ] || [ "$BEFORE_SHA" = "0000000000000000000000000000000000000000" ]; then
            diagram-sync
          else
            git diff -z --name-only --diff-filter=d "$BEFORE_SHA" "$AFTER_SHA" \
              | { grep -zE "$DIAGRAM_PATTERN" || echo "No diagram files changed." >&2; } \
              | xargs -0 -r diagram-sync --files
          fi

      - name: Commit generated diagrams
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          # diagrams/ may not exist yet if nothing has been generated
          git add diagrams/ 2>/dev/null || true
          if git diff --staged --quiet; then
            echo "No diagram changes to commit."
          else
            git commit -m "chore: auto-export diagrams [skip ci]"
            # main may have moved while diagrams were rendering
            git pull --rebase origin main
            git push
          fi

      # outcome, not conclusion: continue-on-error turns the conclusion into success
      - name: Fail if any diagram failed to render
        if: steps.generate.outcome == 'failure'
        run: |
          echo "::error::Some diagrams failed to render. The ones that succeeded were committed; see the Generate diagrams step for details."
          exit 1

No secrets setup required — GITHUB_TOKEN with contents: write works out of the box for unprotected branches. If your main branch is protected and blocks pushes from GITHUB_TOKEN, save a fine-grained PAT (Contents: read and write) as the PAT_TOKEN secret; the workflow picks it up automatically. See the Provider Guides for the ready-to-use workflow file.


Requirements

  • Node.js 20+
  • Each provider requires its own CLI tool — install only what you need:
    • PlantUML: Java 11+, PlantUML, and Graphviz (needed for every diagram type except sequence diagrams) — see PlantUML guide
    • Mermaid: see Mermaid guide
    • Graphviz: see Graphviz guide
    • Draw.io: requires draw.io and xvfb (Linux only) — diagram-sync auto-uses xvfb-run for headless rendering when no display is available — see Draw.io guide
    • D2: see D2 guide
    • Excalidraw: requires @swiftlysingh/excalidraw-cli — SVG and PNG, no browser required — see Excalidraw guide
    • BPMN: requires bpmn-to-image — SVG, PNG and PDF — on CI, patch with --no-sandbox after install (see BPMN guide)

Providers are detected at runtime and missing ones are skipped with a warning.


Common Use Cases

  • How to automate PlantUML diagram generation in CI/CD
  • How to automate Mermaid diagram generation in CI/CD
  • How to automate Graphviz diagram generation in CI/CD
  • How to convert Draw.io files to images automatically in CI/CD
  • How to automate D2 diagram generation in CI/CD
  • How to export Excalidraw files to SVG or PNG automatically in CI/CD
  • How to automate BPMN process diagram generation in CI/CD
  • How to keep README architecture diagrams up to date automatically
  • How to sync architecture diagrams from source files
  • How to generate architecture diagrams on GitHub Actions
  • How to treat architecture diagrams as code
  • Documentation-as-code workflow for PlantUML, Mermaid, D2, and more

Links


License

MIT — Buffden