Skip to main content
Streamdown applies a complete set of typographic styles out of the box. All standard Markdown elements are styled using Tailwind CSS utility classes so content is legible immediately without any additional configuration.

Layout and spacing

The outermost container uses space-y-4 (via a [&>*] selector for Tailwind v3/v4 compatibility) to add consistent vertical rhythm between top-level blocks. First and last child margins are reset to prevent double-spacing at the edges.
app/page.tsx
// The container div always has these classes:
// space-y-4 whitespace-normal
// [&>*:first-child]:mt-0 [&>*:last-child]:mb-0
<Streamdown>{markdown}</Streamdown>
You can extend or override the container with the className prop:
app/page.tsx
<Streamdown className="max-w-prose mx-auto">{markdown}</Streamdown>

Headings

All six heading levels are supported. Each applies mt-6 mb-2 font-semibold with a size that scales from text-3xl down to text-sm:
ElementTailwind classes
<h1>mt-6 mb-2 font-semibold text-3xl
<h2>mt-6 mb-2 font-semibold text-2xl
<h3>mt-6 mb-2 font-semibold text-xl
<h4>mt-6 mb-2 font-semibold text-lg
<h5>mt-6 mb-2 font-semibold text-base
<h6>mt-6 mb-2 font-semibold text-sm
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6

Inline text

Bold

Rendered as <span class="font-semibold"> (not <strong>).
**Bold text** or __also bold__

Italic

Rendered as a standard <em> element with browser-default italic styling.
*Italic text* or _also italic_

Strikethrough

GitHub Flavored Markdown strikethrough via remark-gfm.
~~Crossed out text~~

Inline code

Rendered with a muted background and monospace font:
rounded bg-muted px-1.5 py-0.5 font-mono text-sm
Use the `Streamdown` component in your app.
To customize inline code appearance without touching block code, use the inlineCode component key. See the Components page.

Superscript and subscript

Both use text-sm for reduced visual weight.
H<sub>2</sub>O and E=mc<sup>2</sup>
Rendered as font-medium text-primary underline. When link safety is enabled (the default), links render as <button> elements that open a confirmation modal before navigating.
[Visit our website](https://example.com)

Lists

Unordered lists

list-inside list-disc whitespace-normal
Nested lists add [li_&]:pl-6 for indentation.

Ordered lists

list-inside list-decimal whitespace-normal

List items

Each <li> applies py-1 for breathing room. Paragraphs inside list items are displayed inline to avoid double-spacing.
- First item
- Second item
  - Nested item

1. First step
2. Second step

Blockquotes

my-4 border-muted-foreground/30 border-l-4 pl-4 text-muted-foreground italic
> "A quote from someone important."
> — Attribution

Horizontal rules

my-6 border-border
---

Tables

Table cells use px-4 py-2 text-sm. Header cells add font-semibold whitespace-nowrap. The <thead> uses bg-muted/80 and <tbody> divides rows with divide-y divide-border.
| Feature   | Supported |
|-----------|-----------|
| Markdown  | ✓         |
| Streaming | ✓         |

Code blocks

Code blocks are rendered by the <CodeBlock> component with Shiki syntax highlighting. Line numbers are shown by default. See the Code Blocks page for full configuration.

Images

Images are wrapped in a responsive container <div> that handles loading states, broken image fallbacks, and preserves aspect ratio.

Customizing typography

Via CSS variables

Change colors and radius globally:
app/globals.css
:root {
  --primary: 217 91% 60%;  /* link color */
  --muted: 214 100% 97%;   /* inline code background */
  --border: 214 32% 91%;   /* table and rule borders */
}

Via data-streamdown selectors

Target individual elements without overriding components:
styles/streamdown.css
[data-streamdown="heading-1"] {
  border-bottom: 2px solid #e2e8f0;
  padding-bottom: 0.5rem;
}

[data-streamdown="inline-code"] {
  font-family: 'Fira Code', monospace;
}

[data-streamdown="blockquote"] {
  font-style: normal;
  background: #f7fafc;
}

Via the components prop

For structural changes:
app/page.tsx
<Streamdown
  components={{
    h1: ({ children, className }) => (
      <h1
        className={`mt-6 mb-2 font-semibold text-3xl border-b pb-2 ${className ?? ''}`}
      >
        {children}
      </h1>
    ),
    blockquote: ({ children }) => (
      <blockquote className="my-4 pl-4 border-l-4 border-blue-400 bg-blue-50 rounded-r">
        {children}
      </blockquote>
    ),
  }}
>
  {markdown}
</Streamdown>
See the Components page for the complete guide to component overrides.

Build docs developers (and LLMs) love