Skip to main content
The @streamdown/mermaid plugin renders Mermaid diagrams from fenced code blocks. Any code block tagged ```mermaid is rendered as an interactive SVG with fullscreen, download, copy, and pan/zoom controls.

Installation

1

Install the package

npm install @streamdown/mermaid
2

Pass the plugin to Streamdown

import { Streamdown } from 'streamdown';
import { mermaid } from '@streamdown/mermaid';

export default function Chat({ markdown }: { markdown: string }) {
  return (
    <Streamdown plugins={{ mermaid }}>
      {markdown}
    </Streamdown>
  );
}
Without the plugin, mermaid code blocks render as plain highlighted code instead of diagrams.

Writing diagrams

Use a fenced code block with the mermaid identifier:
```mermaid
graph TD
    A[Start] --> B{Decision}
    B -->|Yes| C[Success]
    B -->|No| D[Try again]
    D --> B
```

Supported diagram types

Flowcharts

Visualize processes and workflows with graph TD, graph LR, and other direction variants.

Sequence diagrams

Model actor interactions with sequenceDiagram.

State diagrams

Represent state machines with stateDiagram-v2.

Class diagrams

Document object-oriented designs with classDiagram.

ER diagrams

Model database schemas with erDiagram.

Gantt charts

Plan project timelines with gantt.

Pie charts

Display proportional data with pie.

Git graphs

Visualize Git workflows with gitGraph.

MermaidOptions

The mermaid prop on <Streamdown> controls runtime rendering options and is separate from plugins.mermaid (which provides the library instance).
interface MermaidOptions {
  config?: MermaidConfig;
  errorComponent?: React.ComponentType<MermaidErrorComponentProps>;
}

Theme configuration

Pass a MermaidConfig object to mermaid.config:
import { Streamdown } from 'streamdown';
import { mermaid } from '@streamdown/mermaid';
import type { MermaidConfig } from '@streamdown/mermaid';

<Streamdown
  plugins={{ mermaid }}
  mermaid={{
    config: {
      theme: 'dark',
      themeVariables: {
        primaryColor: '#ff6b6b',
        primaryTextColor: '#fff',
        lineColor: '#f5f5f5',
      },
    },
  }}
>
  {markdown}
</Streamdown>
Built-in themes: default, dark, forest, neutral, base. The plugin’s default configuration is:
{
  startOnLoad: false,
  theme: 'default',
  securityLevel: 'strict',
  fontFamily: 'monospace',
  suppressErrorRendering: true,
}

Custom error component

When a diagram fails to parse, Streamdown renders a built-in error state. You can replace it with your own component:
interface MermaidErrorComponentProps {
  chart: string;   // The original Mermaid source
  error: string;   // Error message from Mermaid
  retry: () => void; // Re-attempt rendering
}
import { Streamdown } from 'streamdown';
import type { MermaidErrorComponentProps } from 'streamdown';
import { mermaid } from '@streamdown/mermaid';

const DiagramError = ({ error, retry }: MermaidErrorComponentProps) => (
  <div className="rounded border border-red-200 bg-red-50 p-4">
    <p className="text-red-700 text-sm">{error}</p>
    <button
      onClick={retry}
      className="mt-2 text-red-600 text-sm underline"
    >
      Retry
    </button>
  </div>
);

<Streamdown
  plugins={{ mermaid }}
  mermaid={{ errorComponent: DiagramError }}
>
  {markdown}
</Streamdown>

Interactive controls

Each rendered diagram includes a toolbar with controls:
ControlDescription
panZoomPan and zoom the diagram
fullscreenOpen the diagram in a fullscreen overlay
downloadDownload the diagram as an SVG file
copyCopy the diagram to the clipboard
Configure controls via the controls prop:
// Enable specific controls
<Streamdown
  plugins={{ mermaid }}
  controls={{
    mermaid: {
      panZoom: true,
      fullscreen: true,
      download: true,
      copy: true,
    },
  }}
>
  {markdown}
</Streamdown>

// Disable all Mermaid controls
<Streamdown
  plugins={{ mermaid }}
  controls={{ mermaid: false }}
>
  {markdown}
</Streamdown>

Plugin API

createMermaidPlugin(options?)

interface MermaidPluginOptions {
  /** Default Mermaid configuration */
  config?: MermaidConfig;
}
import { createMermaidPlugin } from '@streamdown/mermaid';

const mermaid = createMermaidPlugin({
  config: {
    theme: 'dark',
    fontFamily: 'monospace',
  },
});

DiagramPlugin

interface DiagramPlugin {
  name: 'mermaid';
  type: 'diagram';
  language: string; // 'mermaid' — the code fence identifier
  getMermaid: (config?: MermaidConfig) => MermaidInstance;
}
getMermaid() returns the initialized Mermaid instance. Passing a config argument calls mermaid.initialize() with a merged configuration before returning.

MermaidInstance

interface MermaidInstance {
  initialize: (config: MermaidConfig) => void;
  render: (id: string, source: string) => Promise<{ svg: string }>;
}

Pre-configured instance

@streamdown/mermaid exports a pre-configured instance with default settings:
import { mermaid } from '@streamdown/mermaid';
// Equivalent to: createMermaidPlugin()

Build docs developers (and LLMs) love