Pele Renderer

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

Quick start

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() })],
})
  • Install pele 1.6.0 yourself. It is an optional peer dependency, pinned to that exact version: its markup changes between releases, and editing in the picture reads it.
  • The Worker is the entry @tiptap-pro/extension-diagrams/pele-worker. Load it with your bundler's Worker import; ?worker is Vite's.
  • Pele is loaded only in the Worker. The page loads /pele, which does not import it.
  • Every kind is registered in the Worker, all 25 Mermaid kinds. The Worker loads them once; the page never does. PELE_DIAGRAM_KINDS lists them, and peleDrawsDiagram(source) is the Renderer's draws.

Options

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

Next to mermaid.js

The document stores the same Mermaid source; only the picture differs. Register one of the two for mermaid: the first Diagram Renderer for a format draws it.

mermaid.jsPele
Draws inA sandboxed iframeA Web Worker
Size, gzipAbout 980 kBAbout 205 kB, in the Worker
KindsEvery kind of the listThe same
EdgesCurvesStraight, right-angled
journeyFaces under a timelineScores as a line
mindmapRadialA tree to both sides
Text in the pictureDouble click, in every kind that has itThe 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, and are written into the SVG. toPeleVariables(theme) lists the mapping.
  • The picture is shown in an <img>, like every diagram.
  • No foreignObject. Labels are SVG text, so PNG, WebP and Word need nothing extra.
  • A source that does not parse shows the error state with Pele's message.
  • A Worker that fails rejects what was waiting; the next diagram starts a new one.

On a server

@tiptap-pro/extension-diagrams/pele-render draws without a page, in Node or 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,
})
  • Text widths come from Pele's built-in font metrics where there is no canvas, so a picture can be a few pixels wider or narrower than in the browser.
  • Word needs a PNG beside an SVG; turn the SVG into one with a rasterizer such as resvg.

Editing in the picture

peleDiagramEditing finds text and shapes in Pele's pictures, as mermaidDiagramEditing does in mermaid.js's (Editing in the picture).

  • A double click opens the text of a flowchart's shapes and edges, a sequence diagram's participants and messages, a state, or a class's name. In the other kinds it opens a text the source writes once, such as a timeline's event or a kanban's card.
  • Dragging a flowchart's shape moves it. The document stores the offset, the same one a drag with mermaid.js stores.
  • A moved shape's edges 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, a subgraph's frame included. Pele does not lay the diagram out again.