npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lexical-mermaid

v0.5.0

Published

Mermaid plugin for Lexical Editor

Readme

lexical-mermaid

A Mermaid diagram plugin for Lexical Editor.

Features

  • 📊 Interactive Diagrams - Embed editable Mermaid diagrams in your editor with click-to-edit functionality
  • 🚀 Easy Integration - Simply add the plugin and node to get started
  • ⌨️ Markdown Syntax Support - Auto-insert diagrams with ```mermaid + Enter
  • 📥 Export Functionality - Export diagrams as SVG or PNG with hover buttons
  • 🎨 Customizable - Configure themes and security levels
  • 📦 Lightweight - Minimal bundle size using peer dependencies
  • 🔧 Full TypeScript Support - Type definitions included

Installation

npm install lexical-mermaid

Peer Dependencies

This package requires the following peer dependencies:

npm install lexical @lexical/react mermaid react react-dom

Minimum versions:

  • lexical >= 0.17.0
  • @lexical/react >= 0.17.0
  • mermaid >= 11.0.0
  • react >= 18.0.0
  • react-dom >= 18.0.0

Basic Usage

1. Add Plugin to Lexical Editor

import { useEffect } from 'react'
import { LexicalComposer } from '@lexical/react/LexicalComposer'
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary'
import {
  MermaidNode,
  MermaidPlugin,
  MermaidMarkdownPlugin,
  initMermaid,
} from 'lexical-mermaid'

const editorConfig = {
  namespace: 'MyEditor',
  nodes: [MermaidNode], // Register MermaidNode
  onError: (error: Error) => {
    console.error(error)
  },
}

function Editor() {
  useEffect(() => {
    // Initialize Mermaid
    initMermaid()
  }, [])

  return (
    <LexicalComposer initialConfig={editorConfig}>
      <RichTextPlugin
        contentEditable={<ContentEditable />}
        placeholder={<div>Enter some text...</div>}
        ErrorBoundary={LexicalErrorBoundary}
      />
      <HistoryPlugin />
      <MermaidPlugin /> {/* Mermaid insertion plugin */}
      <MermaidMarkdownPlugin /> {/* ```mermaid syntax support */}
    </LexicalComposer>
  )
}

2. Insert Mermaid Diagram from Button

import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { INSERT_MERMAID_COMMAND, getDefaultMermaidCode } from 'lexical-mermaid'

function Toolbar() {
  const [editor] = useLexicalComposerContext()

  const insertMermaid = () => {
    editor.dispatchCommand(INSERT_MERMAID_COMMAND, getDefaultMermaidCode())
  }

  return (
    <button onClick={insertMermaid}>
      Insert Mermaid Diagram
    </button>
  )
}

3. Insert with Markdown Syntax

Type the following in the editor:

```mermaid

Press Enter, and it will automatically convert to a Mermaid diagram.

4. Use Custom Templates

import { INSERT_MERMAID_COMMAND } from 'lexical-mermaid'

const flowchartTemplate = `graph TD
    A[Start] --> B{Decision}
    B -->|Yes| C[Process A]
    B -->|No| D[Process B]
    C --> E[End]
    D --> E`

function insertFlowchart() {
  editor.dispatchCommand(INSERT_MERMAID_COMMAND, flowchartTemplate)
}

5. Export Diagrams

Diagrams can be exported as SVG or PNG files. Export buttons appear when you hover over a diagram.

Using the built-in UI:

  • Hover over any Mermaid diagram
  • Click the "SVG" or "PNG" button in the top-right corner
  • The file will be automatically downloaded with a timestamp

Programmatic export:

import { exportSVG, exportPNG } from 'lexical-mermaid'

// Export as SVG
const result = await exportSVG(svgString)
if (!result.success) {
  console.error('Export failed:', result.error)
}

// Export as PNG with custom filename
const result = await exportPNG(svgString, 'my-diagram.png')

Export filename format:

  • Default: mermaid-diagram-YYYY-MM-DD-HHMMSS.svg or .png
  • Example: mermaid-diagram-2025-12-29-153045.png

API

Exports

Nodes

  • MermaidNode - Lexical node representing a Mermaid diagram
  • $createMermaidNode(code: string) - Create a MermaidNode
  • $isMermaidNode(node) - Check if a node is a MermaidNode

Plugins

  • MermaidPlugin - Register Mermaid insertion command
  • MermaidMarkdownPlugin - Detect and auto-convert ```mermaid syntax

Commands

  • INSERT_MERMAID_COMMAND - Command to insert Mermaid diagrams

Components

  • MermaidComponent - Mermaid diagram display component
  • MermaidEditor - Mermaid code editor component

Utilities

  • initMermaid(config?: MermaidConfig) - Initialize Mermaid library
  • validateMermaidCode(code: string) - Validate Mermaid code
  • renderMermaid(code: string, elementId: string) - Render Mermaid diagram
  • getDefaultMermaidCode() - Get default Mermaid code
  • exportSVG(svgString: string, filename?: string) - Export diagram as SVG file
  • exportPNG(svgString: string, filename?: string) - Export diagram as PNG file

Type Definitions

  • MermaidTheme - Mermaid theme configuration
  • MermaidConfig - Mermaid configuration options
  • MermaidNodeData - MermaidNode data type
  • SerializedMermaidNode - Serialized MermaidNode
  • ExportFormat - Export format type ('svg' | 'png')
  • ExportResult - Export operation result
  • ExportOptions - Export configuration options
  • MermaidComponentStyles - Style customization for MermaidComponent
  • MermaidComponentClassNames - ClassName customization for MermaidComponent
  • MermaidEditorStyles - Style customization for MermaidEditor
  • MermaidEditorClassNames - ClassName customization for MermaidEditor
  • MermaidErrorRenderer - Custom error renderer function type
  • MermaidLoadingRenderer - Custom loading renderer function type

Context

  • MermaidStyleProvider - Context provider for style customization
  • useMermaidStyle() - Hook to access style context
  • MermaidStyleContextValue - Context value type

Configuration

Mermaid Initialization Options

import { initMermaid } from 'lexical-mermaid'

initMermaid({
  theme: 'dark', // 'default' | 'dark' | 'forest' | 'neutral'
  securityLevel: 'strict', // 'strict' | 'loose' | 'antiscript'
  startOnLoad: false,
  logLevel: 'error',
})

Supported Diagram Types

All Mermaid diagram types are supported:

  • Flowchart
  • Sequence Diagram
  • Class Diagram
  • State Diagram
  • Entity Relationship Diagram
  • Gantt Chart
  • Pie Chart
  • Git Graph
  • And more

See Mermaid Documentation for details.

Style Customization

You can customize the appearance of Mermaid diagrams and editors by providing styles and classNames through the MermaidPlugin.

Using inline styles:

import { MermaidPlugin } from 'lexical-mermaid'

function Editor() {
  return (
    <LexicalComposer initialConfig={editorConfig}>
      <MermaidPlugin
        componentStyles={{
          diagramContainer: {
            padding: '2rem',
            backgroundColor: '#f5f5f5',
          },
          exportButton: {
            backgroundColor: '#ff5722',
          },
        }}
        editorStyles={{
          container: {
            borderColor: '#ff5722',
          },
          saveButton: {
            backgroundColor: '#4caf50',
          },
        }}
      />
      {/* ... */}
    </LexicalComposer>
  )
}

Using CSS classes:

<MermaidPlugin
  componentClassNames={{
    container: 'my-mermaid-container',
    diagramContainer: 'my-diagram',
    exportButton: 'my-export-btn',
  }}
  editorClassNames={{
    container: 'my-editor-container',
    textarea: 'my-textarea',
  }}
/>

Customizable elements:

MermaidComponent (Display Mode):

  • container - Outer wrapper
  • diagramContainer - Diagram display area
  • diagramContent - SVG content wrapper
  • exportButtonContainer - Export buttons wrapper
  • exportButton - SVG/PNG export buttons
  • errorContainer - Error message area
  • loadingContainer - Loading state display

MermaidEditor (Edit Mode):

  • container - Editor wrapper
  • hint - Hint text
  • textarea - Code input area
  • buttonContainer - Button wrapper
  • saveButton - Save button
  • cancelButton - Cancel button
  • deleteButton - Delete button

Note: Both styles and classNames can be used together. Inline styles take precedence over default styles.

Custom Error and Loading Components

You can provide custom render functions for error and loading states:

import type { MermaidErrorRenderer, MermaidLoadingRenderer } from 'lexical-mermaid'

const customErrorRenderer: MermaidErrorRenderer = (error) => (
  <div style={{ padding: '1rem', backgroundColor: '#ffe0e0', color: '#cc0000' }}>
    <h3>Oops! Something went wrong</h3>
    <p>{error}</p>
    <button onClick={() => console.log('Retry')}>Retry</button>
  </div>
)

const customLoadingRenderer: MermaidLoadingRenderer = () => (
  <div style={{ textAlign: 'center', padding: '2rem' }}>
    <div className="spinner" />
    <p>Loading diagram...</p>
  </div>
)

function Editor() {
  return (
    <LexicalComposer initialConfig={editorConfig}>
      <MermaidPlugin
        renderError={customErrorRenderer}
        renderLoading={customLoadingRenderer}
      />
      {/* ... */}
    </LexicalComposer>
  )
}

Renderer function signatures:

  • MermaidErrorRenderer: (error: string) => React.ReactNode
  • MermaidLoadingRenderer: () => React.ReactNode

These custom renderers completely replace the default error and loading UI, giving you full control over their appearance and behavior.

Development

Testing with Storybook

# Start Storybook
npm run storybook

# Open http://localhost:6006 in your browser

Building

# Build the plugin
npm run build

# Development with watch mode
npm run dev

# Type checking
npm run type-check

Project Structure

lexical-mermaid/
├── src/
│   ├── components/      # React components
│   ├── nodes/           # Lexical nodes
│   ├── plugins/         # Lexical plugins
│   ├── stories/         # Storybook stories
│   ├── types/           # TypeScript type definitions
│   ├── utils/           # Utilities
│   └── index.ts         # Entry point
├── .storybook/          # Storybook configuration
└── dist/                # Build output

License

MIT License - See LICENSE for details.

Contributing

Bug reports and feature requests are welcome on GitHub Issues.

References