Pele Renderer

The entry point @tiptap-pro/extension-diagrams/pele draws Mermaid diagrams with Pele, a Mermaid renderer by Obsidian. Pele draws in a Web Worker and needs no DOM and no sandboxed iframe. It is about 5 times smaller to load than mermaid.js. It draws every Mermaid kind a diagram holds, and no charts.
New tab

Quick start

npm install pele@1.6.0
import { Diagrams } from '@tiptap-pro/extension-diagrams'
import { peleDiagramRenderer } from '@tiptap-pro/extension-diagrams/pele'
import PeleWorker from '@tiptap-pro/extension-diagrams/pele-worker?worker'

Diagrams.configure({
  diagramRenderers: [peleDiagramRenderer({ worker: () => new PeleWorker() })],
})

pele is an optional peer dependency, pinned to exactly 1.6.0. Its markup changes between releases, and editing in the diagram reads that markup.

The Worker is the entry point @tiptap-pro/extension-diagrams/pele-worker. Load it with your bundler's Worker import. ?worker is the Vite form.

Only the Worker loads Pele and registers the 25 Mermaid kinds. Your page loads only the entry point @tiptap-pro/extension-diagrams/pele. PELE_DIAGRAM_KINDS lists the kinds. peleDrawsDiagram(source) is the Renderer's draws function.

Options

OptionTypeDescription
worker() => PeleWorkerPortRequired. Starts the Worker, once, for the first diagram. A Worker is a PeleWorkerPort
idstringDefault 'pele'
labelstringDefault 'Mermaid (Pele)'

Next to mermaid.js

The document stores the same Mermaid source for both. Only the drawing differs. Register one of the two for the mermaid format, because the first Diagram Renderer for a format draws it.

mermaid.jsPele
Draws inA sandboxed iframeA Web Worker
Size, gzippedAbout 980 kBAbout 205 kB, in the Worker
KindsEvery kind of the listThe same
EdgesCurvesStraight, at right angles
journeyFaces under a timelineScores as a line
mindmapRadialA tree to both sides
Text editing in the diagramDouble click, in every kind that has textThe same
Dragging shapesFlowchartsThe same
On a serverNeeds a browserRuns in Node, with renderPeleDiagram

How it draws

  • Links and images in the source are dropped. click … href and @{ img: … } draw nothing.
  • Colors come from the --tt-flow-diagram-* custom properties, as for mermaid.js. Pele writes them into the SVG. toPeleVariables(theme) lists the mapping.
  • The diagram is shown in an <img>, like every diagram.
  • There is no foreignObject. Labels are SVG text, so PNG, WebP and Word exports need nothing extra.
  • A source that does not parse shows the error state with Pele's message.
  • A Worker that fails rejects every diagram that was waiting for it. The next diagram starts a new Worker.

On a server

The entry point @tiptap-pro/extension-diagrams/pele-render draws without a page, in Node or in a Worker of your own:

import { defaultDiagramTheme } from '@tiptap-pro/extension-diagrams/core'
import { renderPeleDiagram } from '@tiptap-pro/extension-diagrams/pele-render'

const { svg, width, height } = renderPeleDiagram({
  format: 'mermaid',
  source: 'flowchart LR\n  A --> B',
  theme: defaultDiagramTheme,
})

Without a canvas, text widths come from Pele's built-in font metrics. So a diagram can be a few pixels wider or narrower than in the browser.

Word needs a PNG next to the SVG. Turn the SVG into a PNG with a rasterizer such as resvg.

Editing in the diagram

peleDiagramEditing finds text and shapes in Pele's SVG, as mermaidDiagramEditing does for mermaid.js. See Editing in the diagram.

  • A double click opens the same texts as with mermaid.js. See What a double click edits.
  • Dragging a flowchart's shape stores the same offset as a drag with mermaid.js.
  • The edges of a moved shape are drawn as straight lines from border to border. Their arrowheads turn with them, and their text sits in the middle.
  • Everything else stays where Pele drew it, including a subgraph's frame. Pele does not lay out the diagram again.