Plugins

Learn about Streamdown's plugin system for rendering and processing.

Streamdown uses a plugin architecture for processing Markdown content. Built-in plugins handle core Markdown processing, while Streamdown plugins provide advanced features like syntax highlighting, diagrams, and math.

Built-in plugins

Built-in plugins process Markdown through two stages: Remark (Markdown syntax) and Rehype (HTML output). These are included and configured by default.

Remark plugins

Remark plugins process Markdown syntax before it's converted to HTML.

remark-gfm

Adds support for GitHub Flavored Markdown (GFM) features:

  • Tables
  • Task lists
  • Strikethrough text
  • Autolinks
  • Footnotes

Example:

| Feature | Supported |
|---------|-----------|
| Tables  | ✓         |
| Tasks   | ✓         |

- [x] Completed task
- [ ] Pending task

~~Strikethrough text~~

Rehype plugins

Rehype plugins process HTML after Markdown has been converted.

rehype-raw

Allows raw HTML elements in Markdown to be preserved and rendered. This enables you to use HTML tags directly in your Markdown content.

Example:

This is **Markdown** with <span style="color: red">raw HTML</span>.

<details>
  <summary>Click to expand</summary>
  Hidden content here
</details>

rehype-sanitize

Sanitizes HTML to prevent XSS attacks and ensure safe rendering of user-generated content.

  • Removes potentially dangerous HTML elements and attributes
  • Configurable allow/deny lists
  • Safe by default

rehype-harden

Additional security hardening for links and images, with control over allowed protocols and URL prefixes.

Default configuration:

{
  allowedImagePrefixes: ['*'],
  allowedLinkPrefixes: ['*'],
  allowedProtocols: ['*'],
  defaultOrigin: undefined,
  allowDataImages: true,
}

Options:

  • allowedImagePrefixes: Array of allowed URL prefixes for images (default: all)
  • allowedLinkPrefixes: Array of allowed URL prefixes for links (default: all)
  • allowedProtocols: Array of allowed URL protocols (default: all)
  • defaultOrigin: Origin to use for relative URLs
  • allowDataImages: Whether to allow data URLs for images (default: true)

Customizing built-in plugins

You can customize or replace the default plugins by passing your own plugin arrays:

app/page.tsx
import { Streamdown, defaultRemarkPlugins, defaultRehypePlugins } from 'streamdown';

// Use all defaults
<Streamdown>{markdown}</Streamdown>

// Customize plugins
<Streamdown
  remarkPlugins={[...Object.values(defaultRemarkPlugins), myCustomPlugin]}
  rehypePlugins={[...Object.values(defaultRehypePlugins), anotherPlugin]}
>
  {markdown}
</Streamdown>

Accessing defaults:

import {
  defaultRemarkPlugins,
  defaultRehypePlugins,
} from 'streamdown';

// defaultRemarkPlugins contains:
// - gfm: [remarkGfm, {}]

// defaultRehypePlugins contains:
// - raw: rehypeRaw
// - sanitize: [rehypeSanitize, {}]
// - harden: [harden, { /* config */ }]

Streamdown plugins

Streamdown plugins provide advanced rendering features for code blocks, diagrams, math, and CJK text. Each plugin is a standalone package with dependencies bundled. Install only what you need:

npm install @streamdown/code @streamdown/mermaid @streamdown/math @streamdown/cjk

Then import the plugins:

app/page.tsx
import { Streamdown } from 'streamdown';
import { code } from '@streamdown/code';
import { mermaid } from '@streamdown/mermaid';
import { math } from '@streamdown/math';
import { cjk } from '@streamdown/cjk';

// KaTeX requires CSS
import 'katex/dist/katex.min.css';

<Streamdown plugins={{ code, mermaid, math, cjk }}>
  {markdown}
</Streamdown>

@streamdown/code

Provides syntax highlighting for code blocks using Shiki.

  • Supports 200+ programming languages
  • Languages are lazy-loaded on demand
  • Dual theme support (light/dark mode)
  • Token caching for performance

Install:

npm install @streamdown/code

Usage:

import { code } from '@streamdown/code';

<Streamdown plugins={{ code }}>
  {markdown}
</Streamdown>

Custom configuration:

import { createCodePlugin } from '@streamdown/code';

const code = createCodePlugin({
  themes: ['github-light', 'github-dark'], // [light, dark]
});

See Code Blocks for details.

@streamdown/mermaid

Renders Mermaid diagrams including flowcharts, sequence diagrams, and more.

  • Interactive controls (fullscreen, download, copy)
  • Custom theming support
  • Error handling with retry

Install:

npm install @streamdown/mermaid

Usage:

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

<Streamdown plugins={{ mermaid }}>
  {markdown}
</Streamdown>

Custom configuration:

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

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

See Mermaid Diagrams for details.

@streamdown/math

Renders mathematical expressions using KaTeX.

  • Fast LaTeX rendering
  • Inline and block math support
  • Requires CSS import

Install:

npm install @streamdown/math

Usage:

import { math } from '@streamdown/math';
import 'katex/dist/katex.min.css';

<Streamdown plugins={{ math }}>
  {markdown}
</Streamdown>

Custom configuration:

import { createMathPlugin } from '@streamdown/math';

const math = createMathPlugin({
  singleDollarTextMath: true, // Enable $...$ syntax
  errorColor: '#ff0000',
});

Getting CSS path:

const cssPath = math.getStyles();
// Returns: "katex/dist/katex.min.css"

See Mathematics for details.

@streamdown/cjk

Improves handling of CJK (Chinese, Japanese, Korean) text with proper emphasis formatting and autolink handling.

  • Correct emphasis formatting near ideographic punctuation (bold, italic, strikethrough)
  • Splits autolinks at CJK punctuation boundaries to prevent URLs from swallowing trailing punctuation
  • Uses remark-cjk-friendly and remark-cjk-friendly-gfm-strikethrough for proper parsing

Install:

npm install @streamdown/cjk

Usage:

import { cjk } from '@streamdown/cjk';

<Streamdown plugins={{ cjk }}>
  {markdown}
</Streamdown>

See CJK Language Support for details.

Plugin performance

The plugins are optimized for performance:

  • Built-in plugin arrays are created once at module level for better caching
  • Shiki languages are lazy-loaded only when needed
  • Token results are cached to avoid re-highlighting
  • KaTeX CSS is only loaded when math syntax is used