The Problem

Developers using Mermaid often need diagram output that works in terminals, CI logs, or environments without a DOM. The upstream renderer is SVG‑only, heavy, and hard‑to‑theme, forcing teams to write custom post‑processing or maintain separate rendering pipelines.

What This Does

beautiful-mermaid supplies a pure‑TypeScript engine that converts Mermaid source into either SVG (via src/renderer.ts and src/theme.ts) or ASCII/Unicode art (via src/ascii/index.ts, src/ascii/draw.ts, src/ascii/canvas.ts). The public API lives in src/index.ts and re‑exports the two entry functions renderMermaid and renderMermaidAscii. Themes are defined in src/theme.ts and applied without touching the DOM, leveraging the shiki highlighter for colour palettes.

How It Is Wired

Execution begins at src/index.ts:

  1. renderMermaid → parses the diagram with src/parser.ts, builds a layout through src/layout.ts (which delegates to src/dagre-adapter.ts for graph positioning), then renders SVG with src/renderer.ts.
  2. renderMermaidAscii → calls src/ascii/index.ts, which creates an AsciiCanvas (src/ascii/canvas.ts), runs the ASCII draw routine (src/ascii/draw.ts), and finally produces a string.

Key dependencies:

  • src/layout.ts imports the most modules (15 outgoing edges) and is the primary stability hotspot (instability 0.71).
  • src/ascii/draw.ts participates in a circular import with src/ascii/grid.ts; both pull types from each other, inflating the blast radius for any change to grid logic.
  • Theme handling (src/theme.ts) and style constants (src/styles.ts) are pure data modules with zero outgoing imports, making them safe to modify.

The import graph shows 51 internal modules and 112 edges; only two modules are involved in cycles, limiting the risk of widespread ripple effects, but the cycle in the ASCII path adds cognitive load.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/beautiful-mermaid
cd beautiful-mermaid

# Install dependencies (npm is inferred from package.json)
npm install

# Build the library (tsup config present)
npm run build   # runs tsup as defined in package.json scripts

Render SVG

import { renderMermaid } from './src/index.js';

const svg = await renderMermaid(`
graph TD
  A[Start] --> B{Decision}
  B -->|Yes| C[Action]
  B -->|No| D[End]
`);
console.log(svg);

Render ASCII

import { renderMermaidAscii } from './src/index.js';

const ascii = renderMermaidAscii('graph LR; A --> B --> C');
console.log(ascii);

The library also ships a browser bundle (dist/beautiful-mermaid.browser.global.js) referenced in the README, but no additional configuration files are required.

Real‑World Use

A CI pipeline can embed diagram generation in markdown reports. For example, a test suite could call renderMermaidAscii on a generated flowchart and paste the result into a GitHub Actions log, giving reviewers a quick visual without opening a browser.

import { renderMermaidAscii } from 'beautiful-mermaid';
import fs from 'fs';

const diagram = fs.readFileSync('src/__tests__/testdata/ascii/cls_basic.txt', 'utf8');
console.log(renderMermaidAscii(diagram));

Code Health & Issues

  • High (soundness) – Import cycle: src/ascii/draw.tssrc/ascii/grid.ts. Break the cycle by extracting shared types into a separate module.
  • High (clarity) – Duplicated code blocks: 47 identical 6‑line snippets across samples-data.ts and multiple test files. Consolidate into shared helpers.
  • High (cognitive load) – Oversized files: samples-data.ts, index.ts, src/layout.ts each exceed 900 lines; consider splitting by responsibility.
  • Medium – High branching density: src/ascii/index.ts, src/ascii/draw.ts, src/dagre-adapter.ts contain >19 branch points in <65 lines, making them harder to reason about. Refactor to strategy tables or smaller functions.
  • Dependency drift: @dagrejs/dagre (^1.1.8), typescript (^5.0.0), shiki (^3.19.0) are 1–2 major versions behind current releases, potentially missing bug fixes and performance improvements.
  • Missing lockfile: No package-lock.json or pnpm-lock.yaml; reproducible builds rely on the bun.lock which is not used by npm. Add an npm lockfile.
  • CI present: GitHub Actions workflow (.github/workflows/ci.yml) runs the test suite, indicating basic quality gates are in place.

The Bottom Line

beautiful-mermaid delivers a functional, zero‑DOM Mermaid renderer with both SVG and terminal‑friendly ASCII outputs. The core architecture is clear, but the codebase suffers from a few large, tightly coupled modules and outdated dependencies. It is suitable for teams that need fast diagram rendering in non‑browser contexts, provided they allocate effort to refactor the identified hot spots and bring the dependency versions up‑to‑date.