Skip to content

pinely-international/mermaid-svg-native

Repository files navigation

mermaid-svg-native

Rendering Mermaid to SVG without "Headless Browser" nor Mermaid monkey-patching.

npm package minimized gzipped size Commitizen friendly

Installation

npm i mermaid-svg-native happy-dom canvas opentype.js

Optional Dependencies

  • happy-dom - For DOM emulation for certain graph types.
  • canvas - For Canvas emulation for certain graph types.
  • opentype.js - For loading and parsing OpenType font files.

Usage

Quick Setup

import { injectMermaidSVGPolyfills, RECOMMENDED_MERMAID_CONFIG } from "mermaid-svg-native"

import OpenSansTTF from "mermaid-svg-native/fonts/open-sans.ttf"
import TrebuchetMsTTF from "mermaid-svg-native/fonts/trebuchet-ms.ttf"

await injectMermaidSVGPolyfills(globalThis, {
  default: OpenSansTTF, 
  "trebuchet ms": TrebuchetMsTTF, 
})

// Must initialize Mermaid after polyfills since it has side-effects.
const { default: mermaid } = await import("mermaid")
mermaid.initialize(RECOMMENDED_MERMAID_CONFIG(globalThis))

const { svg } = await mermaid.render("diagram-id", "graph TD; A-->B;")
console.log(svg)

// import { writeFileSync } from "fs"
// writeFileSync("diagram.svg", svg) // Save SVG to file to view it.

Advanced Setup

import {
  loadOpenTypeFonts,

  injectDOMPolyfill,
  injectDOMCanvasPolyfill,
  injectDOMPointPolyfill,
  injectSvgBBoxPolyfill,
} from "mermaid-svg-native"

// Register fonts for SVG BBox Polyfill.
Object.assign(SvgBBox.fonts, await loadOpenTypeFonts(fontsPathsToLoad))

injectDOMPolyfill(globalThis)
injectDOMCanvasPolyfill(globalThis)
injectDOMPointPolyfill(globalThis)
injectSvgBBoxPolyfill(globalThis)

const { default: mermaid } = await import("mermaid")
mermaid.initialize({
  securityLevel: "loose", // Required to render.
  htmlLabels: false, // Required to switch to SVG text rendering.
  flowchart: { htmlLabels: false },

  // Other configurations to your taste.
  startOnLoad: false,
  wrap: true,
  markdownAutoWrap: true,
  gantt: {
    barGap: 15,
    useWidth: window.innerWidth
  }
})

You must specify securityLevel: "loose" (reference) and htmlLabels: false to enable SVG text rendering in Mermaid.

Custom DOM Polyfill

If you're already using a DOM polyfill like jsdom or happy-dom, you can skip the injectDOMPolyfill step and only inject the necessary polyfills for Canvas, DOMPoint, and SVG BBox.

However, you should make sure that CSS computed styles are supported in your DOM polyfill, as Mermaid relies on them for accurate rendering.

Motivation

Mermaid is a popular diagramming and charting tool that generates SVG diagrams from text-based descriptions. However, rendering Mermaid diagrams in Node.js environments typically requires a headless browser (like Puppeteer) or monkey-patching Mermaid's internal functions to work around the lack of DOM and Canvas APIs.

This library provides polyfills for the necessary DOM and Canvas APIs, allowing Mermaid to render SVG diagrams natively in Node.js without the overhead of a headless browser or the fragility of monkey-patching.

This approach offers several benefits:

  • Performance: Eliminates the need for a headless browser, resulting in faster rendering speed.
  • Resource Efficiency: Reduces memory and CPU usage by avoiding the overhead associated with running a browser instance.
  • Bundle size: Smaller bundle size compared to solutions that require a headless browser.
  • No Browser Dependencies: No more loading heavy browser packages and machine incompatibility issues. You can run it on a very restricted environment.
  • Stability: Avoids monkey-patching, which can break with Mermaid updates, leading to more stable and maintainable code.
  • Simplicity: Provides a straightforward way to render Mermaid diagrams in Node.js environments. Can be easily integrated into various Node.js applications, including server-side rendering, static site generation, and more. Don't require running bash scripts or managing browser dependencies.

Caveats

  • Font Management: Users must provide font files for accurate text measurement and rendering. The library includes default fonts used by Mermaid. Learn more in the Font Management document.
  • SVG Features: While the library aims to support the necessary SVG features for Mermaid diagrams, there may be small issues compared to a full browser environment. Complex diagrams or advanced SVG features may not render perfectly.
  • Line Breaks: Line breaks likely won't be displayed accurately right now, as the library does not yet currently support it, but it's planned for future releases.
  • SVG Only: Only SVG-based text measurement and rendering are supported. HTML labels or other non-SVG rendering methods are not supported since they require HTML layout polyfills - this library covers only SVG measurements.

About

No "Headless Browser" Mermaid Rendering To SVG

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published