Streamdown renders Markdown elements using a built-in set of React components. TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/vercel/streamdown/llms.txt
Use this file to discover all available pages before exploring further.
components prop lets you replace any of these with your own implementation, giving you full control over the rendered HTML structure, styling, and behavior.
Basic usage
app/page.tsx
Overridable elements
You can supply a custom component for any of the following keys:| Key | Element | Default styles |
|---|---|---|
h1 | <h1> | mt-6 mb-2 font-semibold text-3xl |
h2 | <h2> | mt-6 mb-2 font-semibold text-2xl |
h3 | <h3> | mt-6 mb-2 font-semibold text-xl |
h4 | <h4> | mt-6 mb-2 font-semibold text-lg |
h5 | <h5> | mt-6 mb-2 font-semibold text-base |
h6 | <h6> | mt-6 mb-2 font-semibold text-sm |
p | <p> | — |
strong | <span> | font-semibold |
a | <a> or <button> | font-medium text-primary underline |
ul | <ul> | list-inside list-disc whitespace-normal [li_&]:pl-6 |
ol | <ol> | list-inside list-decimal whitespace-normal [li_&]:pl-6 |
li | <li> | py-1 [&>p]:inline |
blockquote | <blockquote> | my-4 border-muted-foreground/30 border-l-4 pl-4 text-muted-foreground italic |
hr | <hr> | my-6 border-border |
table | wrapped <table> | Table with controls panel |
thead | <thead> | bg-muted/80 |
tbody | <tbody> | divide-y divide-border |
tr | <tr> | border-border |
th | <th> | whitespace-nowrap px-4 py-2 text-left font-semibold text-sm |
td | <td> | px-4 py-2 text-sm |
code | Code block + inline code | Syntax-highlighted <CodeBlock> or <code> |
img | <div> with image + fallback | Responsive image container |
sup | <sup> | text-sm |
sub | <sub> | text-sm |
section | <section> | Footnotes handling |
inlineCode | <code> (inline only) | Virtual key — see below |
Component props (TypeScript types)
Each component in thecomponents map receives a union of:
- The standard HTML element props for its tag (e.g.
React.ComponentProps<"h1">) - The
ExtraPropstype, which adds:node— the HAST (Hypertext Abstract Syntax Tree) node for this element, useful for reading raw AST properties
Important: default styles are not inherited
app/page.tsx
Inline code: the inlineCode key
The code key covers both fenced code blocks (with syntax highlighting, copy buttons, and Mermaid support) and inline code spans. Overriding code replaces the entire pipeline.
To customize only inline code spans without affecting block code, use the special inlineCode virtual key:
app/page.tsx
inlineCode handles inline spans while code handles fenced code blocks.
app/page.tsx
Streaming state in custom components
TheuseIsCodeFenceIncomplete hook lets a custom code component detect whether its code fence is still being streamed. This is useful for deferring expensive rendering (syntax highlighting, diagram parsing) until the block is complete.
app/page.tsx
true when all three conditions are met:
isAnimating={true}on the parent<Streamdown>- The component is in the last block being rendered
- That block contains an unclosed code fence (an opening
```without a closing```)
false and your component renders normally — even while the rest of the markdown continues streaming.
Custom links
app/page.tsx
Overriding the
a component bypasses the built-in link-safety modal. If you need link safety, implement your own confirmation flow inside the custom component or leave a unoverridden.Preserving table interactivity
When you override thetable component, the built-in copy and download action buttons are lost. To restore them, import the action components and place them inside your custom table wrapper:
app/page.tsx
TableDownloadButton:
Custom HTML tags
You can render custom tags from AI responses (like<mention>, <source>, etc.) by combining allowedTags with components:
app/page.tsx
literalTagContent:
allowedTags and literalTagContent prop references.