TanStack Markdown’s performance strategy is architectural: keep parsing synchronous, keep the AST simple, split entry points, and leave expensive optional work outside the core.
The generated browser bundle report records:
| Entry | Gzip | Brotli |
|---|---|---|
| parser | 4.6 KB | 4.2 KB |
| HTML renderer | 6.4 KB | 5.8 KB |
| React adapter | 6.3 KB | 5.8 KB |
| docs preset | 2.4 KB | 2.2 KB |
| callouts extension | 0.4 KB | 0.3 KB |
React is externalized, and the highlighter measurement uses only a callback stub. Exact generated bytes live in the size report.
The maintained benchmark records parse, pre-parsed rendering, parse-and-render, and external-highlighter paths against the pinned comparison packages. Timings vary by runtime, CPU, fixture shape, and dependency version, so the generated benchmark report is the only source of current CPU results.
import { parseMarkdown } from '@tanstack/markdown/parser'
import { renderHtml } from '@tanstack/markdown/html'Avoid the React adapter in non-React code. Import individual extensions instead of the docs preset when only one capability is required.
For content that changes less often than it is viewed, parse during ingestion or the build. Cache the serializable AST and render it for each target. The measured AST renderer is several times faster than parsing and rendering together.
Highlighting often costs more than Markdown parsing and can bring language grammars, themes, or WASM. Run it at build time or on the server when possible. The Markdown package will never import a highlighter from its core paths.
pnpm run size
pnpm run benchBundle budgets are also enforced in the test suite so an accidental dependency or code-size regression fails CI.