Skip to main content
Registers custom or external diagram types to extend Mermaid’s built-in diagram support. This allows you to add new diagram syntaxes and renderers.

Signature

async function registerExternalDiagrams(
  diagrams: ExternalDiagramDefinition[],
  options?: {
    lazyLoad?: boolean;
  }
): Promise<void>

Parameters

diagrams
ExternalDiagramDefinition[]
required
Array of external diagram definitions to register.
options
object
Configuration options for registration.

Return value

Promise<void> - Resolves when registration is complete (and diagrams are loaded if lazyLoad is false).

Examples

Basic external diagram registration

import mermaid from 'mermaid';

const myCustomDiagram = {
  id: 'custom',
  detector: (text) => {
    return text.match(/^\s*custom/) !== null;
  },
  loader: async () => {
    // Dynamically import your diagram implementation
    const { diagram } = await import('./diagrams/custom/customDiagram.js');
    return { id: 'custom', diagram };
  }
};

await mermaid.registerExternalDiagrams([myCustomDiagram]);

Registering multiple diagrams

const externalDiagrams = [
  {
    id: 'timeline',
    detector: (text) => text.trim().startsWith('timeline'),
    loader: async () => {
      const { diagram } = await import('./diagrams/timeline.js');
      return { id: 'timeline', diagram };
    }
  },
  {
    id: 'mindmap',
    detector: (text) => text.trim().startsWith('mindmap'),
    loader: async () => {
      const { diagram } = await import('./diagrams/mindmap.js');
      return { id: 'mindmap', diagram };
    }
  }
];

await mermaid.registerExternalDiagrams(externalDiagrams);

Eager loading

// Load diagrams immediately instead of lazy loading
await mermaid.registerExternalDiagrams(
  [myCustomDiagram],
  { lazyLoad: false }
);

// All diagrams are now loaded and ready

Advanced detector with config

const advancedDiagram = {
  id: 'advanced',
  detector: (text, config) => {
    // Use config to influence detection
    const enableAdvanced = config?.advanced?.enabled ?? true;
    
    if (!enableAdvanced) {
      return false;
    }
    
    return /^\s*advanced/.test(text);
  },
  loader: async () => {
    const { diagram } = await import('./diagrams/advanced.js');
    return { id: 'advanced', diagram };
  }
};

await mermaid.registerExternalDiagrams([advancedDiagram]);

Complete diagram implementation example

// diagrams/custom/customDiagram.js
export const diagram = {
  db: {
    clear: () => {
      // Clear diagram state
    },
    getAccTitle: () => 'Custom Diagram',
    getAccDescription: () => 'A custom diagram',
    setAccTitle: (title) => {
      // Set title
    },
    setAccDescription: (desc) => {
      // Set description
    },
    getDiagramTitle: () => 'Custom',
    setDiagramTitle: (title) => {
      // Set diagram title
    }
  },
  renderer: {
    draw: async (text, id, version) => {
      // Render the diagram
      const svg = document.getElementById(id);
      // Your rendering logic here
    }
  },
  parser: {
    parse: async (text) => {
      // Parse the diagram text
      // Validate syntax and build internal representation
    }
  },
  styles: () => {
    // Return CSS styles for the diagram
    return '.custom { fill: blue; }';
  }
};

// main.js
const customDiagram = {
  id: 'custom',
  detector: (text) => /^\s*custom/.test(text),
  loader: async () => {
    const { diagram } = await import('./diagrams/custom/customDiagram.js');
    return { id: 'custom', diagram };
  }
};

await mermaid.registerExternalDiagrams([customDiagram]);

// Now you can use it
const { svg } = await mermaid.render('test', 'custom\n  node1 -> node2');

Using with initialization

import mermaid from 'mermaid';

// Register diagrams first
await mermaid.registerExternalDiagrams([customDiagram]);

// Then initialize
mermaid.initialize({
  theme: 'default',
  // Custom diagram config
  custom: {
    // Custom options
  }
});

// Render
await mermaid.run();

Usage notes

  • Must be called before attempting to render diagrams of the registered types
  • Detectors are checked in registration order
  • If multiple detectors match, the first registered one is used
  • With lazyLoad: true (default), diagram code is only loaded when first needed
  • With lazyLoad: false, all diagram implementations are loaded immediately
  • External diagrams have access to the same configuration system as built-in diagrams

Diagram definition structure

Your diagram loader must return an object with:
  • id: String identifier matching the registration
  • diagram: Object containing:
    • db: Database/state management object
    • renderer: Object with draw() method
    • parser: Object with parse() method
    • styles: Optional function returning CSS
    • init: Optional initialization function

Build docs developers (and LLMs) love