
Pele is a dependency-free JavaScript library that renders Mermaid diagrams as SVG.
It handles every built-in diagram type in Mermaid and can rearrange supported layouts for narrower containers.
Pele renders synchronously, with a choice between a raw SVG string and a mounted diagram that responds to container resizing.
You can use CSS variables to control diagram colors and fonts.
Features
- SVG output for use in HTML pages and generated content.
- Touch, mouse, and keyboard zoom controls for large diagrams.
- Source updates through a mounted diagram controller.
- Diagram labels and layout spacing that adapt to narrow widths.
- Individual diagram imports and on-demand type loading.
- Reusable parsed diagrams for rendering at different widths.
- Configurable input limits, error handling, and URL filtering.
How To Use It
Installation
Load the main JavaScript from a CDN. The script exposes the pele global and includes all built-in diagram types.
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pele.global.js"></script>
Or install the package with NPM:
npm install pele
Basic Usage
Create a container and call pele.mount() with Mermaid syntax. Use a block-level container whose width does not depend on the SVG.
<div id="diagram" class="diagram-container"></div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/pele.global.js"></script> <script> const source = `flowchart LR A[Mermaid source] --> B[SVG diagram] B --> C[Web page]`; pele.mount(document.getElementById('diagram'), source); </script>
Render an SVG String with ES Modules
Use render() when an application needs an SVG string for a static preview or generated content. The function is synchronous. Match fontFamily to the CSS font used for diagram labels, especially when --pele-font is set.
import { render } from 'pele';
const source = `sequenceDiagram
participant Client
participant Server
Client->>Server: Request
Server-->>Client: Response`;
const container = document.getElementById('diagram');
const styles = getComputedStyle(container);
const fontFamily = styles.getPropertyValue('--pele-font').trim() || styles.fontFamily;
const { svg } = render(source, { fontFamily });
container.innerHTML = svg;
Update a Diagram and Handle Resizing
mount() observes container width changes, reads fonts from CSS, and returns a controller for later updates. Pending web fonts and container resizes trigger automatic redraws. Call refresh() after changing the font or moving the container. Use destroy() when you no longer need observation.
import { mount } from 'pele';
const diagram = mount(document.getElementById('diagram'), `flowchart LR
A[Draft] --> B[Review]`);
diagram.update(`flowchart LR
A[Draft] --> B[Review] --> C[Published]`);
// After changing the container font or moving it:
diagram.refresh();
// During component teardown:
// diagram.destroy();
For one-off render() calls, pass maxWidth when the layout needs to adapt. Your application must call render() again after a container resize. By default, supported layouts can switch direction below 640 pixels. Set autoDirection: false to preserve the direction specified in the Mermaid source.
const { svg } = render(source, {
maxWidth: document.getElementById('diagram').clientWidth,
autoDirection: false
});
Zoom and Pan
Mounted diagrams use zoom: 'auto' by default. Zoom becomes available when a diagram is scaled down to fit its container. Set zoom: true to enable it for every mounted diagram, or zoom: false to disable it. Controls include pinch, Ctrl/Cmd plus wheel, drag, double-click, and keyboard commands when the diagram has focus. An ordinary wheel scrolls the page.
import { mount } from 'pele';
const diagram = mount(document.getElementById('diagram'), source, {
zoom: { always: true, maxScale: 3, controls: true }
});
// Zoom is also available from the mounted controller:
diagram.zoom?.zoomTo(1.5);
To add zoom to an SVG created with render(), use enableZoom(element, options). Call the zoom controller’s refresh() if the SVG changes.
Load Only the Diagram Types You Need
The pele entry point includes all diagram types. For smaller initial bundles, use pele/core and register individual diagram modules.
import { register, render } from 'pele/core';
import flowchart from 'pele/diagrams/flowchart';
import sequence from 'pele/diagrams/sequence';
register(flowchart, sequence);
const { svg } = render('flowchart LR\n A --> B');
For applications that receive different diagram types at runtime, pele/lazy loads each type on first use. It includes renderAsync(), mountAsync(), and load(). When updating a diagram from mountAsync() to another type, call load() for that type before update().
import { load, renderAsync } from 'pele/lazy';
await load('flowchart');
const { svg } = await renderAsync('flowchart LR\n A --> B');
Styling and Themes
Set CSS variables on a parent element or the root SVG (.pele). Theme color changes take effect immediately. If a font changes, call refresh() to measure label widths again. Mermaid style, classDef, and linkStyle declarations can set fixed colors that do not follow CSS theme changes.
.diagram-container {
--pele-bg: #ffffff;
--pele-fg: #222222;
--pele-surface: #f3f5f8;
--pele-surface-alt: #e8edf5;
--pele-border: #8795a5;
--pele-line: #334155;
--pele-accent: #2563eb;
--pele-font: system-ui, sans-serif;
}
@media (prefers-color-scheme: dark) {
.diagram-container {
--pele-bg: #111827;
--pele-fg: #f3f4f6;
--pele-surface: #1f2937;
--pele-surface-alt: #374151;
--pele-border: #6b7280;
--pele-line: #d1d5db;
--pele-accent: #93c5fd;
}
}
CSS Custom Properties
| Variable | Default and purpose |
|---|---|
--pele-bg | #ffffff. Background color. |
--pele-fg | #1f1f1f. Primary text. |
--pele-muted | #6e6e6e. Secondary text. |
--pele-line | #1f1f1f. Edges and arrowheads. |
--pele-surface | #f3f3f3. Node fill. |
--pele-surface-alt | #e6e6e6. Subgraph fill. |
--pele-border | #8a8a8a. Node and subgraph borders. |
--pele-accent | #5b7bd5. Highlights. |
--pele-critical | #e45756. Critical Gantt tasks and high Kanban priorities. |
--pele-error | #e45756. Error text inside a mounted diagram. |
--pele-font | Measured font. Regular labels. |
--pele-font-mono | Measured font. Monospace labels. |
--pele-title-weight | bold. Diagram title weight. |
--pele-heading-weight | bold. Section and class-heading weight. |
--pele-bold-weight | bold. Bold label weight. |
--pele-radius | 4px. Rounded corners. |
Series Color Variables
| Variable | Default |
|---|---|
--pele-series-1 | #4c78a8 |
--pele-series-2 | #f58518 |
--pele-series-3 | #54a24b |
--pele-series-4 | #e45756 |
--pele-series-5 | #72b7b2 |
--pele-series-6 | #eeca3b |
--pele-series-7 | #b279a2 |
--pele-series-8 | #9d755d |
Zoom Control Position Variables
The zoom buttons accept --pele-zoom-top, --pele-zoom-right, --pele-zoom-bottom, and --pele-zoom-left for positioning.
Public SVG Classes
Pele exposes these SVG classes for element-level styling. Node groups also carry a data-id attribute containing the corresponding Mermaid node ID.
| Class | Element |
|---|---|
pele | Root SVG element. |
pele-flowchart | Root SVG of a flowchart. |
pele-title | Diagram title. |
pele-node | Node group. |
pele-edge | Edge group. |
pele-edge-label | Edge label. |
pele-cluster | Subgraph. |
pele-cluster-label | Subgraph title. |
pele-label | Node label text. |
pele-marker | Arrowhead or edge marker. |
pele-icon | Icon. |
To style the label of the Mermaid node start:
.pele-node[data-id="start"] .pele-label {
fill: var(--pele-accent);
}
API Reference
Functions and Entry Points
| API | Signature or behavior |
|---|---|
render(source, options?) | Synchronously returns a RenderResult from Mermaid text or a parsed DiagramModel. Throws PeleError on failure. |
mount(element, text, options?) | Renders into an HTML element, observes sizing and fonts, and returns a Mounted controller. |
parse(text, options?) | Returns a ParsedDiagramModel for reuse in render(). Accepts limit, maxEdges, and config. |
detectType(text) | Returns the detected DiagramType or null, even when the type is not registered. |
supports(text) | Returns whether the detected type is registered or loaded. Does not validate syntax. |
enableZoom(element, options?) | Attaches zoom and pan to a rendered diagram and returns a Zoom controller. |
register(...diagrams) | Registers individual diagram modules when using pele/core. |
renderAsync(source, options?) | Renders with on-demand diagram type loading from pele/lazy. |
mountAsync(element, text, options?) | Loads and mounts a diagram from pele/lazy; returns a mounted controller asynchronously. |
load(type) | Loads a diagram type ahead of use from pele/lazy. |
RenderOptions
| Option | Type, default, and purpose |
|---|---|
measurer | TextMeasurer. Browser canvas measurement or a built-in width table by default. |
fontFamily | string, sans-serif. Font for regular labels. |
fontFamilyMono | string, monospace. Monospace label font. |
fontSize | number, 16. Base size in pixels. |
idPrefix | string. Prefix for SVG accessibility title and description IDs. Each diagram needs a unique value; mount() generates one. |
responsive | boolean, true. Allows SVG to shrink to its container; set false for fixed pixel dimensions. |
maxWidth | number. Available layout width in pixels. |
autoDirection | boolean, true. Allows responsive direction changes where applicable. |
directionBreakpoint | number, 640. Width threshold in pixels. |
now | number | Date, current time. Reference time for Gantt charts. |
padding | number. Diagram padding in pixels. |
limit | number, 50000. Maximum source characters. |
outputLimit | number, 4000000. Maximum SVG characters. |
maxEdges | number, 5000. Maximum flowchart or agentflow edges. |
linkSchemes | string[], ['http', 'https', 'mailto', 'tel']. Allowed URL link schemes. |
imageSchemes | string[], ['http', 'https']. Allowed image URL schemes. |
linkRel | string, noopener. Link rel attribute. |
links | boolean, true. Allows diagram links. |
images | boolean, true. Allows diagram images. |
icons | (name: string) => string | null | undefined. Supplies trusted SVG markup for icons. |
config | object. Default Mermaid settings; frontmatter and directives can override them. |
MountOptions and Mounted Controller
MountOptions inherits every RenderOptions entry above and introduces four additional options. mount() and update() display invalid diagram source inside the container.
| Option | Type and behavior |
|---|---|
onRender | (result: RenderResult) => void. Called after every successful render. |
onError | (error: unknown) => void. Called after initial errors, failed updates, and automatic redraw failures. |
zoom | boolean | 'auto' | ZoomOptions, default 'auto'. Enables zoom when a diagram shrinks, always, never, or with custom settings. |
sanitize | (svg: string) => Node. Calls an application-supplied SVG sanitizer before insertion and uses the returned Node. |
| Member | Purpose |
|---|---|
result | Latest RenderResult, or undefined before any successful render. |
source | The last supplied Mermaid text, even if it failed. |
error | Most recent failure, or undefined. |
zoom | Zoom controller, or undefined when disabled. |
update(text, options?) | Updates the source and optionally replaces options. Hidden diagrams can defer redraw. |
refresh() | Re-renders only when container width or fonts have changed. |
destroy() | Stops observation and retains the SVG in the container. |
ZoomOptions and Zoom Controller
| Option | Type and default |
|---|---|
always | boolean, false. Enables zoom even when the diagram fits. |
maxScale | number, 3. Maximum zoom scale, relative to natural size 1. |
controls | boolean, true. Displays zoom buttons. |
labels | { zoomIn?, zoomOut?, reset? }. Button labels, English by default. |
| Member | Purpose |
|---|---|
scale | Current scale; 1 is natural size. |
fit | Scale at which the full diagram is visible. |
zoomBy(factor) | Multiplies the scale by a factor. |
zoomTo(scale) | Sets the zoom level. |
reset() | Returns to the fit scale. |
refresh() | Recalculates after replacing the SVG in the container. |
destroy() | Removes zoom behavior and resets the diagram. |
RenderResult, LinkInfo, and Error Handling
render() returns an SVG string with dimensions, type information, and link details. Internal links refer to note identifiers and need application-controlled navigation.
| RenderResult field | Value |
|---|---|
svg | string. Complete SVG markup. |
width | number. Natural width in pixels. |
height | number. Height in pixels. |
type | DiagramType. Pele’s detected type. |
mermaidType | MermaidType. Corresponding Mermaid type. |
links | LinkInfo[]. Diagram links. |
Each links entry has these fields:
| LinkInfo field | Value |
|---|---|
id | Identifier of the linked diagram element. |
href | URL for an external link or note identifier for an internal link. |
internal | boolean. Whether the link refers to an internal note. |
PeleError extends the JavaScript Error class. Unlike mount(), render() and parse() throw for parsing or rendering failures. Error messages can contain the original diagram text. Insert error text with textContent, never innerHTML.
| PeleError property | Value |
|---|---|
message | string. Error text. |
code | string. Error category. |
type | string | null. Pele diagram type, if detected. |
mermaidType | string | null. Mermaid diagram type, if detected. |
line | number. One-based line of the problem; 0 when unavailable. |
column | number. One-based column; 0 when unavailable. |
snippet | string. Source excerpt with a column indicator, or an empty string. |
| Error code | Meaning |
|---|---|
unsupported-diagram | Unknown diagram type or a type that has not been registered. |
syntax | Invalid diagram syntax. |
semantic | Invalid meaning in parsed content. |
limit | Source, output, nesting, or edge constraint exceeded. |
For a UI that accepts arbitrary Mermaid text, catch PeleError and display the message safely:
import { PeleError, render } from 'pele';
try {
document.getElementById('diagram').innerHTML = render(source).svg;
} catch (error) {
if (!(error instanceof PeleError)) throw error;
document.getElementById('diagram').textContent = error.message;
}
Diagram Types and Mermaid Compatibility
Pele accepts all built-in diagram types from Mermaid 12.1.0+.
| Diagram | Mermaid syntax keyword |
|---|---|
| Flowchart | graph, flowchart |
| Swimlane | swimlane-beta |
| Sequence | sequenceDiagram |
| Class | classDiagram |
| State | stateDiagram, stateDiagram-v2 |
| Entity relationship | erDiagram |
| Gantt | gantt |
| Git graph | gitGraph |
| Pie | pie |
| Mindmap | mindmap |
| Kanban | kanban |
| Timeline | timeline |
| User journey | journey |
| Quadrant chart | quadrantChart |
| XY chart | xychart, xychart-beta |
| Requirement | requirementDiagram |
| Sankey | sankey, sankey-beta |
| Architecture | architecture-beta |
| C4 | C4Context, C4Container, C4Component, C4Dynamic, C4Deployment |
| Block | block, block-beta |
| Agentflow | agentflow-beta |
| Railroad | railroad-beta, railroad-ebnf-beta, railroad-abnf-beta, railroad-peg-beta |
| Tree view | treeView-beta |
| Cynefin | cynefin-beta |
| Wardley map | wardley-beta |
| Event modeling | eventmodeling |
| Use case | usecase-beta |
| Venn | venn-beta |
| Ishikawa | ishikawa, ishikawa-beta |
| Packet | packet, packet-beta |
| Radar | radar-beta |
| Treemap | treemap, treemap-beta |
| Info | info |
Diagram Type Names in the JavaScript API
detectType() and RenderResult.type use Pele’s type names. The mermaidType field retains Mermaid’s type name for the cases where they differ.
| Mermaid source keyword | type | mermaidType |
|---|---|---|
graph, flowchart | flowchart | flowchart-v2 |
flowchart-elk | flowchart | flowchart-elk |
classDiagram | class | classDiagram |
stateDiagram | state | stateDiagram |
railroad-beta | railroad | railroad |
railroad-ebnf-beta | railroad | railroadEbnf |
railroad-abnf-beta | railroad | railroadAbnf |
railroad-peg-beta | railroad | railroadPeg |
Rendering Untrusted Diagram Text
Pele escapes labels, filters styles and URLs, and limits input and SVG length. A host application must control icon markup, link navigation, Mermaid configuration, and any stricter SVG sanitization policy. The icons callback inserts the SVG markup it returns as-is. Internal link identifiers are not filtered as URLs. Images can trigger network requests when displayed. linkSchemes and imageSchemes replace the default allowed schemes, although javascript:, data:, and vbscript: are always blocked. For time limits, run rendering in a worker that the application can terminate.
To preview untrusted text without clickable links or embedded images, disable both explicitly:
const { svg } = render(source, { links: false, images: false });
Alternatives and Related Resources
- Render Mermaid Diagrams to SVG or ASCII Art – beautiful-mermaid
- Render Mermaid Diagrams in HTML with mermaid-element
- SVG Flowchart Generator With D3.js – flowcharty







