TanStack
TanStack

Markdown

alpha

Tiny, fast Markdown for docs and AI streams.

Turn your content into a simple, portable document tree. Parse once, cache it, and render it as HTML, React, or Octane.

Docs
article.md
---
title: Ship the docs
---

# One source

Parse it **once**. Render it where the product needs it.

- cache the tree
- index the text
- choose a renderer
root · 3 blocks
frontmatter · string
heading · depth: 1
paragraph · 3 inline nodes
list · 3 items

Parse once. Render wherever you need it.

Keep a portable AST you can cache, inspect, reuse, and render in any framework without parsing it all over again.

Parsing locally
article.mdeditable source
{
  "type": "root",
  "frontmatter": "title: Durable content",
  "children": [
    {
      "type": "heading",
      "depth": 1,
      "id": "one-source-many-destinations",
      "children": [
        {
          "type": "text",
          "value": "One source, many destinations"
        }
      ]
    },
    {
      "type": "paragraph",
      "children": [
        {
          "type": "text",
          "value": "Parse the document "
        },
        {
          "type": "strong",
          "children": [
            {
              "type": "text",
              "value": "once"
            }
          ]
        },
        {
          "type": "text",
          "value": ", then keep the tree."
        }
      ]
    },
    {
      "type": "list",
      "ordered": false,
      "items": [
        {
          "type": "listItem",
          "children": [
            {
              "type": "paragraph",
              "children": [
                {
                  "type": "text",
                  "value": "cache it at the edge"
                }
              ]
            }
          ]
        },
        {
          "type": "listItem",
          "children": [
            {
              "type": "paragraph",
              "children": [
                {
                  "type": "text",
                  "value": "index its text"
                }
              ]
            }
          ]
        },
        {
          "type": "listItem",
          "children": [
            {
              "type": "paragraph",
              "children": [
                {
                  "type": "text",
                  "value": "render it with React or HTML"
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "type": "blockquote",
      "children": [
        {
          "type": "paragraph",
          "children": [
            {
              "type": "text",
              "value": "The renderer can change. The document does not."
            }
          ]
        }
      ]
    }
  ]
}

Made for streaming.

Broken formatting, partial responses, unfinished code blocks. We can handle it.

Complete
Accumulated source
# Streaming response

The model can send **ordinary Markdown** as it thinks.

- accumulated text is reparsed on each update
- unfinished markers stay out of the way
- React and HTML stay in sync

```ts
const text = responseSoFar
return render(text)
```

[Unsafe links stay text-only](javascript:alert("nope"))
React output

Streaming response

The model can send ordinary Markdown as it thinks.

  • accumulated text is reparsed on each update
  • unfinished markers stay out of the way
  • React and HTML stay in sync
const text = responseSoFar
return render(text)

Unsafe links stay text-only

Complete input, reparsed309 / 309 chars

Yep, we support that.

Headings, tables, footnotes, code fences, and plenty more, with a few less-common cases left out to keep things small and fast.

Inside the profile
  • Headings and emphasis
  • Lists and task lists
  • Tables and footnotes
  • Fenced code with metadata
  • Links, images, and references
  • Frontmatter
Outside the contract
  • Every CommonMark edge case
  • Arbitrary async plugin chains
  • MDX or JSX evaluation
  • A bundled highlighter
  • A general HTML sanitizer

User-generated Markdown? 😍Malicious XSS? ❌

Render user content with fewer worries. We escape raw HTML and block executable URLs by default, and you stay in control of custom rendering.

Untrusted input
<script>alert("not today")</script>

[Run code](javascript:alert("nope"))

**Trusted Markdown still renders.**
Deterministic HTML
<p>&lt;script&gt;alert(&quot;not today&quot;)&lt;/script&gt;</p>
<p>Run code</p>
<p><strong>Trusted Markdown still renders.</strong></p>
HTML escapedExecutable URL removedMarkdown preserved

Who needs server components?

Markdown parsing so light your server can find another excuse to feel important. Parse and render in the browser, with separate imports for the pieces you need to keep your bundle small.

TanStack HTML7.13 KB
marked12.47 KB
unified stack36.62 KB
markdown-it52.06 KB
5.29 KB
Parser
7.09 KB
React adapter
7.06 KB
Octane adapter
2.37 KB
docs preset

Markdown 1.0.0 · measured October 1, 2026 with Node 26.3.1. Gzip sizes for minified browser builds of public entry exports. Renderers include the parser; framework runtimes and highlighters are excluded. Feature sets differ, and sizes vary with imports and build tools. Measurement details

Your code. Your colors.

Got a favorite syntax highlighter? Bring it along, or use our own TanStack Highlight. We handle the Markdown and code-block markup, you handle the colors.

TanStackHighlight

A tiny, synchronous highlighter that plugs right into Markdown’s code fences.

Explore Highlight

Partners

Gold
Vercel
CodeRabbit
Render
Netlify
Lovable
Cloudflare
Railway
Silver
AG Grid
Clerk
OpenRouter
WorkOS
SerpApi
Bronze
Sentry
Scarf
Unkey
Prisma
OSS Sponsors

Sponsors get special perks like private discord channels, priority issue requests, and direct support!