v0.1.0shadcn/ui compatible

Mermaid diagrams
for React

A customizable, shadcn-compatible Mermaid.js renderer with built-in zoom and pan. Copy. Paste. Render.

No diagram code provided

<Mermaid />

component

Pure renderer component. Pass a Mermaid chart string and an optional config, get a rendered SVG. Handles loading, error states, and dynamic imports automatically.

Props

PropTypeDefaultDescription
chart*string-The Mermaid diagram definition string to render.
configMermaidConfig-Configuration object for theming, fonts, and diagram-specific options.
classNamestring-Additional CSS classes for the container element.
onSuccess(svg: string) => void-Callback fired with the rendered SVG string on success.
onError(error: string) => void-Callback fired with the error message on render failure.
debounceTimenumber300Delay in ms before rendering triggers (useful for live editors).

Basic Usage

my-diagram.tsxtsx
import { Mermaid } from "@/components/mermaidcn/mermaid"

export function MyDiagram() {
  return (
    <Mermaid
      chart={`sequenceDiagram
        participant C as Client
        participant S as Server
        C->>S: POST /api/data
        S-->>C: 200 OK`}
    />
  )
}

Preview

Basic Mermaid

No diagram code provided

With Theming

themed-diagram.tsxtsx
import { Mermaid } from "@/components/mermaidcn/mermaid"

export function ThemedDiagram() {
  return (
    <Mermaid
      chart={`flowchart LR
        A([Input]) --> B[Process]
        B --> C([Output])`}
      config={{
        theme: "forest",
        fontSize: 16,
        fontFamily: "Inter, sans-serif",
      }}
    />
  )
}

Preview

Forest Theme

No diagram code provided

<ZoomPan />

component

High-performance canvas-based zoom and pan engine. Optimized for large images and complex diagrams with smooth interpolation and high-DPI support. For Mermaid diagrams, using <MermaidPreview /> is recommended as it handles the SVG-to-Canvas conversion automatically.

Props

PropTypeDefaultDescription
imageSrc*string-The source URL or Data URL of the image to render on the canvas.
onLoad() => void-Callback fired when the image successfully loads.
childrenReact.ReactNode-Optional content rendered in a hidden container (useful for lifecycle management).
controls(api) => ReactNode-Render-prop exposing zoomIn, zoomOut, resetZoom, centerView, and scalePercent.
classNamestring-Additional CSS classes for the outer wrapper.
minScalenumber0.1Minimum zoom scale.
maxScalenumber5Maximum zoom scale.
initialScalenumber1Initial zoom scale on mount.
zoomStepnumber0.1Scale increment per scroll tick.
isLoadingbooleanfalseWhether the component is in a loading state.
loadingFallbackReact.ReactNode-Custom UI to show during the loading state.

Wrapping Mermaid in ZoomPan

zoomable-diagram.tsxtsx
import { Mermaid } from "@/components/mermaidcn/mermaid"
import { ZoomPan } from "@/components/mermaidcn/zoom-pan"

export function ZoomableDiagram() {
  const [svgOutput, setSvgOutput] = React.useState("")

  const imageSrc = React.useMemo(() => {
    if (!svgOutput) return ""
    const bytes = new TextEncoder().encode(svgOutput)
    const binString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join("")
    return `data:image/svg+xml;base64,${btoa(binString)}`
  }, [svgOutput])

  return (
    <ZoomPan
      imageSrc={imageSrc}
      className="h-[400px]"
      controls={({ zoomIn, zoomOut, resetZoom, scalePercent }) => (
        <div className="flex items-center gap-2 p-2">
          <button onClick={zoomOut}>-</button>
          <span>{scalePercent}%</span>
          <button onClick={zoomIn}>+</button>
          <button onClick={resetZoom}>Reset</button>
        </div>
      )}
    >
      <Mermaid 
        chart="classDiagram\n  class Animal" 
        onSuccess={setSvgOutput}
      />
    </ZoomPan>
  )
}

Preview

Zoom & Pan (scroll to zoom, drag to pan)

No diagram code provided

useZoomPan Hook

For fully custom implementations, use the useZoomPan hook to get zoom state and control functions without the wrapper component.

custom-zoom.tsxtsx
import { useZoomPan } from "@/components/mermaidcn/zoom-pan"

export function CustomZoom() {
  const { zoomIn, zoomOut, resetZoom, scalePercent } = useZoomPan()

  return (
    <div>
      <p>Current zoom: {scalePercent}%</p>
      <button onClick={zoomIn}>Zoom In</button>
      <button onClick={zoomOut}>Zoom Out</button>
      <button onClick={resetZoom}>Reset</button>
    </div>
  )
}

<MermaidPlayground />

component

The full batteries-included playground environment. Combines the editor, controls, and preview into a single cohesive interface.

Props

PropTypeDefaultDescription
defaultValuestring-Initial Mermaid diagram code for the editor.
classNamestring-Additional CSS classes for the container.

Usage

my-playground.tsxtsx
import { MermaidPlayground } from "@/components/mermaidcn/mermaid-playground"

export function Editor() {
  return (
    <MermaidPlayground 
      defaultValue="graph TD; A-->B;" 
      className="h-[500px]" 
    />
  )
}

<MermaidPreview />

component

A standalone component that wraps the Renderer and ZoomPan features along with export controls (SVG, PNG, Copy). This is the component used within the Playground.

Props

PropTypeDefaultDescription
chart*string-The Mermaid diagram definition string.
configMermaidConfig-Configuration object for rendering.
svgOutput*string-The rendered SVG string (controlled state).
onSvgOutputChange*(svg: string) => void-Callback called when the SVG is successfully rendered.
classNamestring-Additional CSS classes for the preview wrapper.

Usage

custom-preview.tsxtsx
import { MermaidPreview } from "@/components/mermaidcn/mermaid-preview"

export function CustomPreview() {
  const [svg, setSvg] = React.useState("")
  
  return (
    <MermaidPreview
      chart="graph TD; A-->B;"
      config={{ theme: 'dark' }}
      svgOutput={svg}
      onSvgOutputChange={setSvg}
    />
  )
}

Installation

Install individual components via the shadcn CLI, or copy the source files directly.

Mermaid Renderer

ZoomPan Wrapper

Mermaid Playground

Manual Installation

1. Install the mermaid dependency:

npm install mermaid

2. Copy the component files into your project:

components/
  mermaidcn/
    mermaid.tsx      # Pure renderer
    zoom-pan.tsx     # Zoom & pan wrapper

3. Import and use:

example.tsxtsx
import { Mermaid } from "@/components/mermaidcn/mermaid"

export function MyDiagram() {
  return (
    <Mermaid
      chart={`sequenceDiagram
        participant C as Client
        participant S as Server
        C->>S: POST /api/data
        S-->>C: 200 OK`}
    />
  )
}