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 />
componentPure renderer component. Pass a Mermaid chart string and an optional config, get a rendered SVG. Handles loading, error states, and dynamic imports automatically.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
chart* | string | - | The Mermaid diagram definition string to render. |
config | MermaidConfig | - | Configuration object for theming, fonts, and diagram-specific options. |
className | string | - | 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. |
debounceTime | number | 300 | Delay in ms before rendering triggers (useful for live editors). |
Basic Usage
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
No diagram code provided
With Theming
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
No diagram code provided
<ZoomPan />
componentHigh-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
| Prop | Type | Default | Description |
|---|---|---|---|
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. |
children | React.ReactNode | - | Optional content rendered in a hidden container (useful for lifecycle management). |
controls | (api) => ReactNode | - | Render-prop exposing zoomIn, zoomOut, resetZoom, centerView, and scalePercent. |
className | string | - | Additional CSS classes for the outer wrapper. |
minScale | number | 0.1 | Minimum zoom scale. |
maxScale | number | 5 | Maximum zoom scale. |
initialScale | number | 1 | Initial zoom scale on mount. |
zoomStep | number | 0.1 | Scale increment per scroll tick. |
isLoading | boolean | false | Whether the component is in a loading state. |
loadingFallback | React.ReactNode | - | Custom UI to show during the loading state. |
Wrapping Mermaid in ZoomPan
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
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.
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 />
componentThe full batteries-included playground environment. Combines the editor, controls, and preview into a single cohesive interface.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
defaultValue | string | - | Initial Mermaid diagram code for the editor. |
className | string | - | Additional CSS classes for the container. |
Usage
import { MermaidPlayground } from "@/components/mermaidcn/mermaid-playground"
export function Editor() {
return (
<MermaidPlayground
defaultValue="graph TD; A-->B;"
className="h-[500px]"
/>
)
}<MermaidPreview />
componentA 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
| Prop | Type | Default | Description |
|---|---|---|---|
chart* | string | - | The Mermaid diagram definition string. |
config | MermaidConfig | - | Configuration object for rendering. |
svgOutput* | string | - | The rendered SVG string (controlled state). |
onSvgOutputChange* | (svg: string) => void | - | Callback called when the SVG is successfully rendered. |
className | string | - | Additional CSS classes for the preview wrapper. |
Usage
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 mermaid2. Copy the component files into your project:
components/
mermaidcn/
mermaid.tsx # Pure renderer
zoom-pan.tsx # Zoom & pan wrapper3. Import and use:
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`}
/>
)
}