Introduction
Streamdown is a React component by Vercel that renders markdown content progressively as it streams in from an LLM. Unlike traditional markdown renderers that re-parse the entire document on each update, Streamdown incrementally parses and renders only the new tokens, eliminating flicker and layout shifts during streaming.
What Streamdown Does
- Renders markdown incrementally as tokens stream from an LLM
- Eliminates visual flicker and layout shifts during generation
- Supports full GitHub Flavored Markdown including tables and code blocks
- Provides syntax highlighting for code blocks in 100+ languages
- Offers a plugin system for custom rendering of markdown elements
Architecture Overview
Streamdown uses an incremental parser that maintains a partial AST as new characters arrive. Rather than re-parsing the full document, it extends the existing tree and patches only the affected DOM nodes. This architecture keeps CPU usage constant regardless of document length, critical for long streaming responses.
Self-Hosting & Configuration
- Install as a standard npm package in any React project
- Zero configuration needed for basic usage
- Customize rendering with component overrides for each element type
- Theme support via CSS variables or Tailwind classes
- SSR-compatible for Next.js and other server-rendering frameworks
Key Features
- Constant-time rendering regardless of document length
- Drop-in API compatibility with react-markdown
- Built-in copy button for code blocks
- Smooth cursor animation at the streaming insertion point
- TypeScript-first with full type definitions
Comparison with Similar Tools
- react-markdown — re-parses entire document on each update causing flicker; Streamdown is incremental
- marked — parse-only library without streaming awareness; Streamdown handles partial inputs
- MDX — compile-time focused; Streamdown handles runtime streaming
- rehype/remark — plugin ecosystem compatible but no streaming support; Streamdown adds it
FAQ
Q: Is it compatible with react-markdown props? A: Yes, it accepts the same component override API for easy migration.
Q: Does it work with any LLM streaming API? A: Yes. Feed it a string that grows over time from any source.
Q: What about non-React frameworks? A: A vanilla JS version is planned; currently React-only.
Q: How does it handle incomplete markdown (like unclosed code blocks)? A: It gracefully renders partial syntax and corrects as more tokens arrive.