How to Use `mermaid.run()` to Programmatically Render Multiple Diagrams with Custom RunOptions

Use mermaid.run() with custom RunOptions to selectively render DOM elements, handle errors gracefully via suppressErrors, and execute postRenderCallback functions after each diagram generates.

The mermaid.run() function in the mermaid-js/mermaid repository provides the primary JavaScript API for programmatically rendering diagrams that already exist in the DOM. Unlike legacy initialization methods, run() offers fine-grained control over which elements to process, how to handle rendering failures, and when to execute custom logic after each diagram completes.

Understanding the mermaid.run() Architecture

The implementation in packages/mermaid/src/mermaid.ts exposes an async run() function that wraps the internal runThrowsErrors() worker. The public API (lines 89-128) catches errors and delegates to the internal renderer, while the RunOptions interface (lines 45-63) defines the configuration contract.

Key components:

  • RunOptions: Defines optional parameters including querySelector, nodes, postRenderCallback, and suppressErrors
  • run(): Entry point that catches errors and optionally re-throws based on suppressErrors
  • runThrowsErrors(): Internal implementation (lines 130-200) that resolves configuration via mermaidAPI.getConfig(), determines target nodes, and orchestrates the rendering loop

Configuring RunOptions Parameters

Selecting Target Elements

The function accepts two mutually exclusive methods for specifying which DOM elements to render:

  1. querySelector: A CSS selector string (defaults to ".mermaid") that finds elements in the document
  2. nodes: A direct reference to a NodeList or array of HTMLElement objects

When both are provided, nodes takes precedence, ignoring the selector entirely (see the branching logic at lines 40-44 in runThrowsErrors).

Error Handling with suppressErrors

The suppressErrors boolean controls error propagation:

  • true: Continues rendering remaining diagrams if one fails, collecting errors silently
  • false: Re-throws the first encountered error immediately (handled in run() lines 15-27)

Executing Post-Render Callbacks

The postRenderCallback function executes after each individual diagram renders successfully, receiving the diagram ID as its argument. This hook is ideal for attaching event listeners, caching SVG output, or logging metrics.

Implementation Examples

Rendering with a Custom CSS Selector

Target only elements with class myDiagram and log each completion:

await mermaid.run({
  querySelector: '.myDiagram',
  postRenderCallback: (id) => {
    console.log('Rendered diagram', id);
  },
});

Processing Specific Node References

Pass a NodeList directly and suppress errors to ensure all diagrams attempt rendering:

const diagramContainers = document.querySelectorAll('.dynamic-diagram');

await mermaid.run({
  nodes: diagramContainers,
  suppressErrors: true,
  postRenderCallback: (id) => {
    const svg = document.getElementById(id).innerHTML;
    mySvgCache.set(id, svg);
  },
});

Implementing Global Error Handling

Catch rendering failures at the application level:

async function renderAll() {
  try {
    await mermaid.run({
      querySelector: '.chart',
      suppressErrors: false,
    });
  } catch (e) {
    console.error('Mermaid rendering failed:', e);
  }
}
renderAll();

Unit Testing with mermaid.run()

Verify multiple diagrams render correctly in test environments:

import mermaid from 'mermaid';

test('multiple diagrams render without crashing', async () => {
  document.body.innerHTML = `
    <div class="mermaid">graph LR; A-->B</div>
    <div class="mermaid">sequenceDiagram; Alice->>Bob: Hello</div>
  `;

  await mermaid.run();
  expect(document.querySelectorAll('svg').length).toBe(2);
});

Core Source Files and Rendering Pipeline

Understanding the underlying implementation helps customize the workflow:

The runThrowsErrors() function skips already-processed elements (those with data-processed attributes), sanitizes diagram definitions, and injects generated SVG into the DOM.

Summary

  • mermaid.run() is the async entry point for rendering diagrams already present in the DOM, located in packages/mermaid/src/mermaid.ts
  • Use querySelector to target elements by CSS class or nodes to pass specific element references directly
  • Set suppressErrors: true to continue rendering multiple diagrams even if individual diagrams fail
  • Implement postRenderCallback to execute custom logic after each diagram renders, such as caching SVG content or attaching listeners
  • The function automatically skips elements marked with data-processed to prevent duplicate rendering

Frequently Asked Questions

What is the difference between mermaid.run() and mermaid.init()?

mermaid.init() is the legacy API that automatically initializes all diagrams on page load with limited configuration options. mermaid.run() provides modern programmatic control via RunOptions, allowing custom element selection, error handling, and post-render callbacks as implemented in packages/mermaid/src/mermaid.ts.

How do I prevent mermaid.run() from re-rendering already processed diagrams?

The internal runThrowsErrors() function automatically checks for the data-processed attribute on each element and skips any diagram already containing this marker. This prevents duplicate rendering when calling run() multiple times on the same page.

Can I use mermaid.run() in Node.js or only in browsers?

mermaid.run() is designed for browser environments because it requires a DOM to query elements and inject SVG. For server-side rendering in Node.js, use the mermaid.render() function directly with a virtual DOM implementation like JSDOM.

How does suppressErrors affect the rendering loop?

When suppressErrors is true, the function collects errors in an array during the rendering loop and continues processing remaining diagrams. When false or undefined, run() re-throws the first error immediately, halting execution as defined in lines 15-27 of packages/mermaid/src/mermaid.ts.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →