Overview
<mermaid-element> brings the declarative simplicity of HTML to diagramming. Instead of manually configuring Mermaid, managing initialization lifecycles, or wrangling script tags, you simply write your Mermaid syntax inside a <mermaid-element> tag and let the browser render it.
<mermaid-element>
graph LR
HTML[Raw HTML Syntax] --> Element[<mermaid-element> Custom Element]
Element --> Engine[Mermaid 12 via jsDelivr CDN]
Engine --> SVG[Rendered SVG in Shadow DOM]
</mermaid-element>
Features
Engineered as a modern, standalone web component for effortless documentation, dashboards, blogs, and interactive tools.
⚡ Zero-Config & Declarative
Place raw Mermaid syntax directly inside the custom element. No manual JavaScript initialization calls required.
📦 Zero Dependencies
Ships as an ultra-lightweight package. Dynamically loads Mermaid 12 from jsDelivr on demand without bloating your app bundle.
🔄 Dynamic Version Switching
Need a specific release? Pass mermaid="10.9.8" or a custom endpoint URL to fetch and render with that exact version.
🔌 Pre-Installed / Bundled Support
Have Mermaid already in your bundle? Set MermaidElement.defaultMermaid = mermaid to use your pre-installed package offline.
🧠 Smart In-Memory Caching
Instances share loaded modules and in-flight promises. Multiple diagrams on the same page will only fetch Mermaid once.
🛡️ Shadow DOM & CSS Parts
Diagram SVGs render in open Shadow Roots to prevent style bleeding. Customize styling using standard CSS ::part() hooks.
Installation & Setup
Install via npm for modern bundlers, or drop in a script tag from a CDN.
Install mermaid-element alone. It will dynamically fetch Mermaid 12 on demand without bloating your node_modules:
npm install mermaid-element
import 'mermaid-element'; // Automatically registers <mermaid-element>
If your application bundles Mermaid locally or runs in an air-gapped environment, install both packages and assign your instance:
npm install mermaid-element mermaid
import mermaid from 'mermaid';
import { MermaidElement } from 'mermaid-element';
// Direct <mermaid-element> to use your local bundled Mermaid library
MermaidElement.defaultMermaid = mermaid;
Include the module directly in any HTML document without build tools:
<script type="module" src="https://cdn.jsdelivr.net/npm/mermaid-element/index.js"></script>
Controlling Mermaid Version
How <mermaid-element> resolves and loads Mermaid libraries.
By default, <mermaid-element> dynamically loads Mermaid 12 on demand from jsDelivr (see Example 1).
Authors can override this per element using the mermaid attribute:
-
Version String: Pass a release version like
mermaid="10.9.8"to fetch that release on demand from the CDN (see Example 2). -
Full URL or Path: Pass a full URL or relative path like
mermaid="https://.../mermaid.esm.min.mjs"to load from a custom endpoint or self-hosted asset (see Example 3).
If your application already bundles Mermaid or operates in an offline / air-gapped environment, you can supply your own default instance instead of fetching from a CDN:
import mermaid from 'mermaid';
import { MermaidElement } from 'mermaid-element';
// Use your pre-installed or pre-configured instance as the default
MermaidElement.defaultMermaid = mermaid;
For script-based setups, <mermaid-element> also automatically detects a globally defined window.mermaid. Individual elements can still override this default by specifying their own mermaid attribute.
🧠 Smart In-Memory Caching
Loaded Mermaid modules and pending load promises are cached in memory by URL. When multiple <mermaid-element> elements share the same version or endpoint on a page, Mermaid is fetched and initialized only once.
Styling Before Upgrade
Before custom elements are registered and upgraded by the browser, they behave like unstyled inline text elements. Because scripts take time to download and execute, you can choose between two strategies for how un-upgraded <mermaid-element> elements appear while loading:
Format the raw Mermaid syntax as a readable monospace code block until the component upgrades:
mermaid-element:not(:defined) {
display: block;
white-space: pre-wrap;
font-family: monospace;
}
Trade-off: Flash of Unstyled Content (FOUC)
The diagram definition is immediately legible while scripts load, but this results in a Flash of Unstyled Content (FOUC): once the custom element registers and Mermaid renders, the raw text abruptly transforms into the rendered SVG diagram.
Hide <mermaid-element> elements completely until they are registered in the CustomElementRegistry:
mermaid-element:not(:defined) {
display: none;
}
Trade-off: Cumulative Layout Shift (CLS)
This completely prevents any flash of raw Mermaid code or unstyled text (no FOUC), but results in a Cumulative Layout Shift (CLS): when the custom element upgrades, the diagram suddenly appears in the document flow and shifts subsequent content downward.
JavaScript API
Full programmatic control over diagram definitions, themes, versions, and lifecycle events.
| Property / Attribute | Type | Description |
|---|---|---|
diagram |
string |
Gets or sets the raw Mermaid syntax. Setting this property triggers an automatic re-render. |
mermaid |
string | null |
Gets or sets the mermaid attribute (version string, URL, or null to default to Mermaid 12). |
theme |
string | null |
Gets or sets the theme attribute (default, neutral, dark, forest, base). |
svg |
SVGSVGElement | null |
Read-only reference to the rendered SVG element inside the shadow root. |
MermaidElement.defaultMermaid |
any |
Static property to specify an explicit pre-configured Mermaid instance to use as the default. |
| Member | Signature / Detail | Description |
|---|---|---|
render() |
Promise<{ svg, diagram } | null> |
Method to manually trigger a diagram re-render. |
@render |
{ detail: { svg: string, diagram: string } } |
Event dispatched when the diagram renders successfully into the Shadow Root. |
@error |
{ detail: { error: Error, diagram: string } } |
Event dispatched when a syntax or rendering error occurs. |
<mermaid-element> exposes internal structural elements via the part attribute so you can style them from your page stylesheet using ::part():
| Part Name | Element | Description |
|---|---|---|
container |
<div class="container"> |
The flex container wrapping the rendered SVG inside the Shadow Root. |
error |
<div class="error"> |
The alert notification container rendered when a syntax error occurs. |
/* Style the diagram container */
mermaid-element::part(container) {
padding: 1.5rem;
background: var(--bg-surface-elevated);
border-radius: 8px;
}
/* Customize the error box */
mermaid-element::part(error) {
border-color: #ef4444;
background-color: #fef2f2;
}
Example 1: Default (Mermaid 12)
When no mermaid attribute is passed, <mermaid-element> uses your configured MermaidElement.defaultMermaid (or window.mermaid) if provided, or defaults to Mermaid 12 dynamically loaded on demand from jsDelivr.
<mermaid-element>
graph TD
subgraph Frontend [Client Tier]
Web[Web Browser]
Mobile[Mobile App]
end
...
</mermaid-element>
Example 2: Dynamic Version (CDN)
Pass a version string or number in the mermaid attribute (e.g. 10.9.8) to dynamically load that version on-demand from cdn.jsdelivr.net.
<mermaid-element mermaid="10.9.8">
sequenceDiagram
autonumber
actor Customer
actor Cashier
...
</mermaid-element>
Example 3: Dynamic Version from URL
If the mermaid attribute starts with https://, http://, or a relative path, it will be loaded directly from that exact URL.
<mermaid-element mermaid="https://cdn.jsdelivr.net/npm/mermaid@11.4.1/dist/mermaid.esm.min.mjs">
stateDiagram-v2
[*] --> Draft
...
</mermaid-element>
Interactive Live Playground
Test diagram types, edit Mermaid syntax live, switch versions, and observe dynamic updates.
<mermaid-element>
graph TD
A[Client Request] --> B[API Gateway]
B --> C{Authentication}
...
</mermaid-element>
Example 5: Error Handling
When invalid Mermaid syntax is provided, <mermaid-element> captures the parse error gracefully and renders an accessible error notification with part="error" without crashing the application.
Example 6: Using <template> for Unescaped Syntax
To avoid browser HTML entity escaping when using special characters like <, >, or HTML node labels, you can wrap your Mermaid definition inside a <template> tag.
<mermaid-element>
<template>
flowchart LR
A["Raw & Unescaped <b>HTML</b>"] --> B["<tag>Node B</tag>"]
B --> C["Node C"]
</template>
</mermaid-element>
Example 7: CSS Shadow Parts (::part)
Use CSS ::part(container) to style the wrapper inside the element's Shadow DOM directly from your page stylesheet.
/* Page CSS */
mermaid-element.styled-part-example::part(container) {
padding: 1.5rem;
background: var(--bg-surface-elevated);
border: 2px dashed var(--primary-color);
border-radius: 10px;
}
<mermaid-element class="styled-part-example">
graph LR
Client[Browser Client] --> LB[Load Balancer]
LB --> App1[App Server 1]
LB --> App2[App Server 2]
</mermaid-element>