vercel/streamdown

streamdown

- Implement, configure, and customize Streamdown — a streaming-optimized React Markdown renderer with syntax highlighting, Mermaid diagrams, math rendering, and CJK support.

Zobacz źródło
Oryginalny dokument Skill

Treść z repozytorium z zachowaniem nagłówków, przykładów, kodu, tabel, linków i obrazów.

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

bash
npm install streamdown

Optional plugins (install only what's needed):

bash
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:

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:

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

3. Basic Usage

tsx
import { Streamdown } from 'streamdown';

<Streamdown>{markdown}</Streamdown>

4. With AI Streaming (Vercel AI SDK)

tsx
'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)

tsx
<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
controls`boolean \object`trueInteractive buttons; download: { filename } sets custom download names
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:

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

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

References

Use these for deeper implementation details:

  • [references/api.md](references/api.md) — Complete props, types, and interfaces
  • [references/plugins.md](references/plugins.md) — Plugin setup, configuration, and customization
  • [references/styling.md](references/styling.md) — CSS variables, data attributes, custom components, theme examples
  • [references/security.md](references/security.md) — Hardening, link safety, custom HTML tags, production config
  • [references/features.md](references/features.md) — Carets, remend, static mode, controls, GFM, memoization, troubleshooting

Example Configurations

Copy and adapt from assets/examples/:

  • [basic-streaming.tsx](assets/examples/basic-streaming.tsx) — Minimal AI chat with Vercel AI SDK
  • [with-caret.tsx](assets/examples/with-caret.tsx) — Streaming with block caret cursor
  • [full-featured.tsx](assets/examples/full-featured.tsx) — All plugins, carets, link safety, controls
  • [static-mode.tsx](assets/examples/static-mode.tsx) — Blog/docs rendering
  • [custom-security.tsx](assets/examples/custom-security.tsx) — Strict security for AI content

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