Streamdown

repository·main·Indexed 24 days ago

https://github.com/vercel/streamdown

A toolkit for rendering streaming Markdown content, featuring the Streamdown component for AI chat interfaces and the remend package for self-healing partial Markdown syntax. Includes support for plugins like code, mermaid, math, and cjk, as well as a Conversation component suite for AI conversation layouts.

Tokens
47.6K
Snippets
140
Records
231
Agent score
89%

What's inside Streamdown

  1. Introduction to Streamdown

    main
    Streamdown is a React component library designed as a drop-in replacement for react-markdown. It is specifically optimized for AI-powered applications that stream Markdown content in real-time. Unlike traditional renderers, Streamdown handles the challenges of tokenized streaming, such as incomplete syntax (e.g., unclosed bold tags), partial code blocks, and unterminated links, by intelligently parsing and progressively formatting content as it arrives.
  2. Apply Scoped Styling to Streamdown instances

    main

    To apply styles to a specific instance of Streamdown without affecting the rest of your application, use the className prop to create a scope. You can then target Streamdown's data attributes within that class in your CSS.

    1. Pass a unique className to the <Streamdown /> component.
    2. Use that class as a parent selector for [data-streamdown] attributes in your CSS.
    <Streamdown className="docs-content">{markdown}</Streamdown>
    .docs-content [data-streamdown="heading-1"] {
      font-family: 'Inter', sans-serif;
    }
    .docs-content [data-streamdown="code-block"] {
      font-family: 'Fira Code', monospace;
    }
  3. Handle code blocks during streaming

    main

    When content is streaming, Streamdown handles incomplete code blocks gracefully by using an unterminated block parser.

    To prevent users from copying incomplete code during a stream, use the isAnimating prop. When isAnimating={true}, the copy buttons are automatically disabled.

    <Streamdown isAnimating={isStreaming}>{markdown}</Streamdown>
    <Streamdown isAnimating={isStreaming}>{markdown}</Streamdown>
  4. Migrate from react-markdown to Streamdown

    main

    Streamdown is a drop-in replacement for react-markdown optimized for AI-powered streaming. It maintains 100% prop compatibility with react-markdown, supporting props like children, components, remarkPlugins, rehypePlugins, remarkRehypeOptions, allowElement, allowedElements, disallowedElements, skipHtml, unwrapDisallowed, and urlTransform.

    Key Benefits of Migration

    • Built-in Plugins: GFM, math (KaTeX), raw HTML, and CJK support are included by default. You can remove remark-gfm, remark-math, rehype-katex, rehype-raw, rehype-harden, remark-cjk-friendly, and remark-cjk-friendly-gfm-strikethrough.
    • Built-in Syntax Highlighting: Shiki is integrated. You can remove shiki or react-syntax-highlighter.
    • Built-in Mermaid: Mermaid diagrams are rendered automatically without custom components.
    • Prestyled Typography: Standard HTML elements (e.g., p, li, h1) are styled out of the box, allowing you to remove custom component overrides and Tailwind prose classes.
    • Internal Memoization: Streamdown handles memoization internally; you can remove any MemoizedReactMarkdown wrappers.
  5. Enable text animations in Streamdown

    main

    To enable per-word streaming animations, import streamdown/styles.css and set the animated prop on the <Streamdown> component. You must also provide the isAnimating prop to control when the animation is active. When isAnimating is false, the animation plugin is excluded, and messages render as plain text with no DOM overhead.

    import { Streamdown } from "streamdown";
    import "streamdown/styles.css";
    
    export default function Page() {
      return (
        <Streamdown animated isAnimating={status === "streaming"}>
          {markdown}
        </Streamdown>
      );
    }
  6. Skip or disable HTML in Markdown

    main

    To control how HTML is handled in your Markdown content:

    • Skip HTML: Use the skipHtml prop to completely ignore raw HTML tags in the Markdown input.
    • Disable HTML: To block all raw HTML rendering, remove rehypeRaw from the rehypePlugins array. You can do this by importing defaultRehypePlugins and filtering out the raw plugin.
    // Skipping HTML
    <Streamdown skipHtml>{markdown}</Streamdown>
    
    // Disabling HTML
    import { defaultRehypePlugins } from 'streamdown';
    const { raw, ...rest } = defaultRehypePlugins;
    <Streamdown rehypePlugins={Object.values(rest)}>{markdown}</Streamdown>
  7. Configure Tailwind CSS for Streamdown

    main

    Streamdown requires Tailwind CSS to style its output. You must ensure the Tailwind scanner includes the Streamdown distribution files. Failure to do this will result in missing styles.

    Tailwind v4

    Add the @source directive to your globals.css. Add a line for each plugin you have installed:

    @source "../node_modules/streamdown/dist/*.js";
    /* If using plugins, add them as well: */
    @source "../node_modules/@streamdown/code/dist/*.js";
    @source "../node_modules/@streamdown/cjk/dist/*.js";
    @source "../node_modules/@streamdown/math/dist/*.js";
    @source "../node_modules/@streamdown/mermaid/dist/*.js";

    Tailwind v3

    Add the path to the content array in your tailwind.config.js:

    module.exports = {
      content: [
        "./app/**/*.{js,ts,jsx,tsx,mdx}",
        "./node_modules/streamdown/dist/*.js",
      ],
    };
    @source "../node_modules/streamdown/dist/*.js";
  8. Install and use Streamdown plugins

    main

    Streamdown uses a plugin architecture where each feature is a standalone package. You can install multiple plugins at once or individually. To use them, pass the imported plugin objects to the plugins prop of the <Streamdown> component.

    npm install @streamdown/code @streamdown/mermaid @streamdown/math @streamdown/cjk
    import { code } from '@streamdown/code';
    import { mermaid } from '@streamdown/mermaid';
    import { math } from '@streamdown/math';
    import { cjk } from '@streamdown/cjk';
    import 'katex/dist/katex.min.css'; // Required for math
    
    <Streamdown plugins={{ code, mermaid, math, cjk }}>
      {markdown}
    </Streamdown>
  9. Configure Static Mode

    main

    Use mode="static" when rendering pre-generated, complete markdown content (like blog posts or documentation) instead of streaming content.

    Benefits of Static Mode:

    • Skips block parsing (renders as a single unit).
    • Assumes markdown is complete and well-formed.
    • Uses optimized rendering for code blocks.
    • Reduces streaming overhead.

    All standard props like plugins, shikiTheme, and mermaid configuration are supported in static mode.

    import { Streamdown } from 'streamdown';
    import { code } from '@streamdown/code';
    
    export default function BlogPost({ content }: { content: string }) {
      return (
        <Streamdown
          mode="static"
          plugins={{ code: code }}
        >
          {content}
        </Streamdown>
      );
    }
  10. Install Streamdown and its plugins

    main

    To use Streamdown, install the core package via npm. You can also install optional plugins for specific features like syntax highlighting, diagrams, math, or CJK support.

    npm install streamdown
    
    # Optional plugins
    npm install @streamdown/code @streamdown/mermaid @streamdown/math @streamdown/cjk