PluginBench
Skill
Official
Review
Audit score 70

streamdown

vercel/streamdown

Streaming-optimized React Markdown renderer with syntax highlighting, diagrams, math, and AI chat integration.

What is streamdown?

Streamdown is a drop-in replacement for react-markdown designed for real-time AI streaming. It renders Markdown with built-in support for code highlighting, Mermaid diagrams, LaTeX math, and CJK text, plus interactive controls and security features like link safety modals.

  • Render Markdown with streaming-optimized performance and caret animations
  • Syntax highlight code blocks in 200+ languages using Shiki
  • Embed and render Mermaid diagrams (flowcharts, sequence, state, etc.)
  • Render LaTeX math expressions via KaTeX
  • Support Chinese, Japanese, and Korean text rendering
  • Control interactive features (copy buttons, link safety modals, custom components)

How to install streamdown

npx skills add https://github.com/vercel/streamdown --skill streamdown
Prerequisites
  • Node.js and npm
  • React 16.8+ (for hooks)
  • Tailwind CSS v3 or v4 configured in your project
  • Optional: @streamdown/code, @streamdown/mermaid, @streamdown/math, @streamdown/cjk plugins
Claude Code
Cursor
Windsurf
Cline

How to use streamdown

  1. 1.Install streamdown: npm install streamdown
  2. 2.Install optional plugins as needed (e.g., npm install @streamdown/code @streamdown/mermaid)
  3. 3.Configure Tailwind CSS: add @source directive (v4) or content entry (v3) for streamdown dist files and any installed plugins
  4. 4.Import Streamdown and wrap your Markdown content: <Streamdown>{markdown}</Streamdown>
  5. 5.For AI streaming, pass isAnimating={true} and caret prop to enable animated cursor
  6. 6.For static mode (blogs/docs), use mode="static" prop
  7. 7.Configure plugins, security, and styling via props (linkSafety, allowedElements, shikiTheme, etc.)

Use cases

Good for
  • Integrate with Vercel AI SDK for real-time AI chat responses with animated carets
  • Render Markdown in static blogs or documentation sites without streaming overhead
  • Display code snippets with syntax highlighting and copy-to-clipboard buttons
  • Embed mathematical equations and diagrams in technical content
  • Build secure AI chat interfaces with link confirmation modals and HTML sanitization
Who it's for
  • React developers building AI chat applications
  • Content creators using Markdown for blogs or documentation
  • Teams integrating Vercel AI SDK into Next.js applications
  • Developers needing fine-grained control over Markdown rendering and security

streamdown FAQ

Why are Tailwind styles missing?

Streamdown requires Tailwind to scan its dist files. Add @source "../node_modules/streamdown/dist/*.js"; to globals.css (v4) or add to content array in tailwind.config.js (v3). Only add @source lines for plugins you have installed.

How do I enable the animated caret for streaming?

Set both the caret prop ("block" or "circle") and isAnimating={true}. The caret only displays when isAnimating is true, typically controlled by your AI SDK's loading state.

How do I render math expressions?

Install @streamdown/math, import 'katex/dist/katex.min.css', add math to plugins, and wrap expressions in $$...$$ (single $ is disabled by default to avoid currency conflicts).

Can I use this with static content like blogs?

Yes. Set mode="static" to disable streaming optimizations. This is ideal for blogs, documentation, and other non-streaming Markdown rendering.

How do I disable the link safety modal?

Pass linkSafety={{ enabled: false }} to the Streamdown component. Link safety is enabled by default for security in AI chat contexts.

Full instructions (SKILL.md)

Source of truth, from vercel/streamdown.


name: streamdown description: >- Implement, configure, and customize Streamdown — a streaming-optimized React Markdown renderer with syntax highlighting, Mermaid diagrams, math rendering, and CJK support. Use when working with Streamdown setup, configuration, plugins, styling, security, or integration with AI streaming (e.g., Vercel AI SDK). Triggers on: (1) Installing or setting up Streamdown, (2) Configuring plugins (code, mermaid, math, cjk), (3) Styling or theming Streamdown output, (4) Integrating with AI chat/streaming, (5) Configuring security, link safety, or custom HTML tags, (6) Using carets, static mode, or custom components, (7) Troubleshooting Tailwind, Shiki, or Vite issues.

Streamdown

Streaming-optimized React Markdown renderer. Drop-in replacement for react-markdown with built-in streaming support, security, and interactive controls.

Quick Setup

1. Install

npm install streamdown

Optional plugins (install only what's needed):

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

2. Configure Tailwind CSS (Required)

This is the most commonly missed step. Streamdown uses Tailwind for styling and the dist files must be scanned.

Tailwind v4 — add to globals.css:

@source "../node_modules/streamdown/dist/*.js";

Add plugin @source lines only for packages you have installed (omitting uninstalled plugins avoids Tailwind errors). See plugin pages for exact paths:

  • Code: @source "../node_modules/@streamdown/code/dist/*.js";
  • CJK: @source "../node_modules/@streamdown/cjk/dist/*.js";
  • Math: @source "../node_modules/@streamdown/math/dist/*.js";
  • Mermaid: @source "../node_modules/@streamdown/mermaid/dist/*.js";

Tailwind v3 — add to tailwind.config.js:

module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx,mdx}",
    "./node_modules/streamdown/dist/*.js",
  ],
};

3. Basic Usage

import { Streamdown } from 'streamdown';

<Streamdown>{markdown}</Streamdown>

4. With AI Streaming (Vercel AI SDK)

'use client';
import { useChat } from '@ai-sdk/react';
import { Streamdown } from 'streamdown';
import { code } from '@streamdown/code';

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat();

  return (
    <>
      {messages.map((msg, i) => (
        <Streamdown
          key={msg.id}
          plugins={{ code }}
          caret="block"
          isAnimating={isLoading && i === messages.length - 1 && msg.role === 'assistant'}
        >
          {msg.content}
        </Streamdown>
      ))}
      <form onSubmit={handleSubmit}>
        <input value={input} onChange={handleInputChange} disabled={isLoading} />
      </form>
    </>
  );
}

5. Static Mode (Blogs, Docs)

<Streamdown mode="static" plugins={{ code }}>
  {content}
</Streamdown>

Key Props

PropTypeDefaultPurpose
childrenstringMarkdown content
mode"streaming" | "static""streaming"Rendering mode
plugins{ code?, mermaid?, math?, cjk? }Feature plugins
isAnimatingbooleanfalseStreaming indicator
caret"block" | "circle"Cursor style
componentsComponentsCustom element overrides
controlsboolean | objecttrueInteractive buttons
linkSafetyLinkSafetyConfig{ enabled: true }Link confirmation modal
shikiTheme[light, dark]['github-light', 'github-dark']Code themes
classNamestringContainer class
allowedElementsstring[]allTag names to allow
disallowedElementsstring[][]Tag names to disallow
allowElementAllowElementCustom element filter
unwrapDisallowedbooleanfalseKeep children of disallowed elements
skipHtmlbooleanfalseIgnore raw HTML
urlTransformUrlTransformdefaultUrlTransformTransform/sanitize URLs

For full API reference, see references/api.md.

Plugin Quick Reference

PluginPackagePurpose
Code@streamdown/codeSyntax highlighting (Shiki, 200+ languages)
Mermaid@streamdown/mermaidDiagrams (flowcharts, sequence, etc.)
Math@streamdown/mathLaTeX via KaTeX (requires CSS import)
CJK@streamdown/cjkChinese/Japanese/Korean text support

Math requires CSS:

import 'katex/dist/katex.min.css';

For plugin configuration details, see references/plugins.md.

References

Use these for deeper implementation details:

Example Configurations

Copy and adapt from assets/examples/:

Common Gotchas

  1. Tailwind styles missing — Add @source directive or content entry for node_modules/streamdown/dist/*.js
  2. Math not rendering — Import katex/dist/katex.min.css
  3. Caret not showing — Both caret prop AND isAnimating={true} are required
  4. Copy buttons during streaming — Disabled automatically when isAnimating={true}
  5. Link safety modal appearing — Enabled by default; disable with linkSafety={{ enabled: false }}
  6. Shiki warning in Next.js — Install shiki explicitly, add to transpilePackages
  7. allowedTags not working — Only works with default rehype plugins
  8. Math uses $$ not $ — Single dollar is disabled by default to avoid currency conflicts