Skip to content

About

ProseMirror plugin for Mermaid diagrams — configurable, extensible, and ready to wrap as a Tiptap extension

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

702 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Prosemirror Mermaid

test codecov Version Downloads npm bundle size NPM License

🧩 A lightweight ProseMirror plugin that renders Mermaid diagrams directly inside the editor — with live updates, caching, and tight SVG cropping.


✨ Features

  • Live rendering — Mermaid diagrams update automatically as you type.
  • Debounced updates — Smooth, performant re-rendering (default: 300 ms).
  • Smart caching — Re-renders only when the diagram source changes.
  • Syntax highlighting — Works seamlessly with lowlight and lowlight-mermaid.
  • Tight SVG cropping — Uses @svg-fns/layout for clean, whitespace-free output.
  • Robust architecture — Follows ProseMirror best practices via widget decorations and plugin-managed lifecycle.

🚀 Installation

pnpm add prosemirror-mermaid

or

npm install prosemirror-mermaid

or

yarn add prosemirror-mermaid

🧩 Usage

import { EditorState } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { mermaidPlugin } from "prosemirror-mermaid";
import mermaid from "mermaid";

// Important: initialize Mermaid yourself
mermaid.initialize({ startOnLoad: false });

const state = EditorState.create({
  schema,
  plugins: [
    // ... other plugins
    mermaidPlugin({ name: "codeBlock" }),
  ],
});

const view = new EditorView(document.querySelector("#editor"), { state });

⚙️ Options

Option Type Default Description
name string 'codeBlock' Node type treated as Mermaid block.
lowlight ReturnType<typeof createLowlight> — Enables syntax highlighting. Registers mermaid, mmd, and mindmap grammars automatically.
debounce number 300 Delay (ms) before re-rendering after edits.
mermaidConfig MermaidConfig — Pass directly to mermaid.initialize().
classList string[] | string — CSS classes applied to each diagram container.

🧠 Node Requirements

Your ProseMirror schema’s Mermaid node (usually codeBlock) must include:

  • language: must be "mermaid", "mmd", or "mindmap".
  • id: unique identifier (e.g., m1234abcd).

This is typically managed by your editor or nodeView logic. If you’re using tiptap, you can generate stable IDs via an addAttributes() extension override.


🧩 Example Integration (Tiptap)

import { CodeBlockLowlight } from "@tiptap/extension-code-block-lowlight";
import { createLowlight } from "lowlight";
import { mermaidPlugin } from "prosemirror-mermaid";
import mermaid from "mermaid";

const lowlight = createLowlight();
mermaid.initialize({ startOnLoad: false });

const editor = useEditor({
  extensions: [
    CodeBlockLowlight.configure({ lowlight }).extend({
      addAttributes() {
        const parentAttrs = this.parent?.() ?? {};

        return {
          ...parentAttrs,
          id: {
            default: () => `m${crypto.randomUUID().slice(0, 8)}`,
            parseHTML: element =>
              element.getAttribute("data-id") || `m${crypto.randomUUID().slice(0, 8)}`,
            renderHTML: attributes => {
              if (!attributes.id) return {};
              return { "data-id": attributes.id };
            },
          },
        };
      },
      addProseMirrorPlugins() {
        return [
          ...(this.parent?.() || []),
          mermaidPlugin({
            name: this.name,
            lowlight: this.options.lowlight,
            classList: "mermaid",
          }),
        ];
      },
    }),
  ],
});

🧰 Internals

  • Uses Decoration.widget to inject rendered SVGs after code blocks.
  • Maintains per-node render cache, debounce timers, and code cache.
  • Relies on @svg-fns/io for safe SVG parsing and tightlyCropSvg for layout cleanup.
  • Handles render errors gracefully with inline messages.

🪄 Example Styling

.mermaid-container {
  display: flex;
  justify-content: center;
  padding: 0.5rem;
  overflow-x: auto;
  background: var(--code-bg, #fafafa);
  border-radius: 0.5rem;
}

🙏 Credits


License

This library is licensed under the MPL-2.0 open-source license.

Please enroll in our courses or sponsor our work.


with 💖 by Mayank Kumar Chaudhari

About

ProseMirror plugin for Mermaid diagrams — configurable, extensible, and ready to wrap as a Tiptap extension

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages