GitHub Flavored Markdown

Extended Markdown features including tables, task lists, strikethrough, and autolinks.

Streamdown includes full support for GitHub Flavored Markdown (GFM) through remark-gfm. This extends standard Markdown with powerful features commonly used on GitHub and other modern Markdown platforms.

Tables

Create formatted tables with alignment options:

| Feature | Supported | Notes |
|---------|-----------|-------|
| Tables | ✅ | Full support |
| Task Lists | ✅ | Interactive |
| Strikethrough | ✅ | ~~Like this~~ |

Renders as:

FeatureSupportedNotes
TablesFull support
Task ListsInteractive
StrikethroughLike this

Column Alignment

Control text alignment using colons in the separator row:

| Left | Center | Right |
|:-----|:------:|------:|
| A | B | C |
| 1 | 2 | 3 |

Result:

LeftCenterRight
ABC
123

Alignment Syntax:

  • :--- - Left-aligned (default)
  • :---: - Center-aligned
  • ---: - Right-aligned

Table Features

Streamdown enhances tables with:

  • Responsive scrolling - Tables scroll horizontally on narrow screens
  • Download button - Export tables as CSV, TSV, or Markdown
  • Hover states - Row highlighting for better readability
  • Proper spacing - Optimized cell padding

Complex Tables

Tables support inline formatting:

| Name | Description | Status |
|------|-------------|--------|
| **Streamdown** | A `react-markdown` replacement | ✅ Active |
| *Feature X* | Under development | 🚧 WIP |
| ~~Old Package~~ | Deprecated | ❌ Removed |

Disabling Table Controls

You can disable the table download button:

<Streamdown controls={{ table: false }}>
  {markdown}
</Streamdown>

Task Lists

Create interactive todo lists:

- [x] Setup project structure
- [x] Install dependencies
- [ ] Write documentation
- [ ] Deploy to production

Renders as:

  • Setup project structure
  • Install dependencies
  • Write documentation
  • Deploy to production

Task List Syntax

  • - [ ] - Unchecked task (whitespace in brackets)
  • - [x] - Checked task (lowercase x)
  • - [X] - Also checked (uppercase X)

Nested Task Lists

Task lists can be nested:

- [ ] Phase 1: Setup
  - [x] Initialize repository
  - [x] Configure build tools
  - [ ] Setup CI/CD
- [ ] Phase 2: Development
  - [ ] Implement features
  - [ ] Write tests

Task Lists in Different Contexts

Task lists work in various contexts:

## Shopping List
- [ ] Milk
- [ ] Eggs
- [x] Bread

> **Note**: Here's a quote with tasks:
> - [x] Complete quote formatting
> - [ ] Add more examples

Strikethrough

Mark text as deleted or outdated:

~~This approach is deprecated~~

Use this **new method** instead.

Result: This approach is deprecated

Multiple Words

Strikethrough works across multiple words:

~~This entire sentence is struck through.~~

In Context

**Before:** ~~500ms response time~~
**After:** 50ms response time ⚡

Result: Before: 500ms response time After: 50ms response time ⚡

URLs and email addresses are automatically converted to links:

Visit https://streamdown.ai for more info.

Contact us at hello@streamdown.ai

No need for explicit link syntax:

Check out github.com/vercel/streamdown

URL Protocols

Autolinks work with common protocols:

  • http:// and https://
  • ftp://
  • mailto:
https://example.com
ftp://files.example.com
mailto:hello@example.com

Line Breaks

In standard Markdown (and GFM), single newlines within a paragraph are treated as soft breaks and rendered as spaces — the lines are combined into one paragraph:

This is line one
This is line two
This is line three

This renders as a single paragraph: "This is line one This is line two This is line three".

To force a visible line break, use one of these approaches:

Two Trailing Spaces (Hard Break)

Add two or more spaces at the end of a line:

Line one··
Line two··
Line three

(where ·· represents two spaces)

Backslash (Hard Break)

Use a trailing backslash:

Line one\
Line two\
Line three

Using remark-breaks

If you want single newlines to always render as <br> without trailing spaces, add the remark-breaks plugin:

import remarkBreaks from "remark-breaks";
import { Streamdown, defaultRemarkPlugins } from "streamdown";

<Streamdown
  remarkPlugins={[...Object.values(defaultRemarkPlugins), remarkBreaks]}
>
  {markdown}
</Streamdown>