TanStack
TanStack

Highlight

alpha

Highlighting built for the web.

Register the languages your docs use, highlight synchronously, and ship one compact semantic HTML tree that every theme can share.

Docs
live output
01
02import { createHighlighter } from '@tanstack/highlight/core'
03import { tsx, css } from './languages'
04
05const highlight = createHighlighter({ languages: [tsx, css] })
06
07const html = highlight(code, {
08 lang: 'tsx',
09 highlight: [2, 4, 5],
10})
sync
semantic classes
escaped HTML

Selective assembly

The registry is the bundle plan.

The core knows no languages. Direct imports make the site’s language set explicit and let the bundler discard everything else.

gzip profileadd only what is used →
coreno languages1.74 KB
tsxcore + TSX3.86 KB
docs9 languages5.83 KB
all25 languages7.96 KB

Semantic output

Change the palette. Keep the markup.

Tokens carry stable semantic classes instead of theme colors. CSS variables recolor the same tree without a second highlighting pass.

output.html
<span class="th-keyword">
const
</span>
emitted once
themes.css
[data-theme=light]
--th-keyword: #a21caf
[data-theme=dark]
--th-keyword: #f0abfc
recolored by CSS

Context-aware scanners

Web languages rarely stay in their lane.

HTML, Vue, Svelte, EJS, Markdown, and JavaScript templates delegate embedded regions only when the nested language is registered.

component.vueregistered: html · ts · css
HTML scanner
<section class="result">
Vue expression → TS
{{ score.toFixed(2) }}
HTML scanner
</section>
script → TS
<script setup lang="ts">
const score: number = 0.98
</script>
style → CSS
<style>.result { color: var(--accent) }</style>

Web

TS · TSX · JS · JSX · CSS · HTML

Content

Markdown · MDX · JSON · YAML

Shell

Bash · Shell · PowerShell

Frameworks

Vue · Svelte · Astro · EJS

cache.ts{2,4-5} ins=5
1const cache = new Map()
2const value = cache.get(key)
3if (value) return value
4const next = await load(key)
5cache.set(key, next)
6return next

Presentation metadata

Annotate the lesson, not the token stream.

Highlight lines, exact character ranges, insertions, deletions, focus, errors, and warnings without changing the source or tokenizer.

Corpus, not toys

Tuned against the docs it will render.

The committed corpus samples 333 fixtures from 2,940 TanStack documentation files. Release checks cover fidelity, deterministic HTML, bundle profiles, and runtime throughput.

TanStack docs corpustimeHTML
TanStack Highlight20 ms364 KiB
Shiki~1.2 s1,252 KiB
2,940 docs files scanned333 committed fixtures10,000+ blocks per gate

Project benchmark report. This measures the tested corpus and output shape, not equivalent grammar accuracy; Shiki targets deeper TextMate fidelity.

Choose by job

A docs highlighter is not an editor highlighter.

Highlight is optimized for known web languages and compact page output, not TextMate completeness, automatic detection, or incremental editor state.

TanStack Highlight

Known docs languages, compact HTML, CSS themes, and annotations matter most.

Shiki

TextMate and VS Code fidelity, broad language coverage, and editor-grade themes are the job.

Sugar High

The smallest straightforward JavaScript and TypeScript path is enough.

Explicit integrations

Drop it into Markdown without hiding the language set.

Every renderer and adapter receives the highlighter you assembled; none imports every language behind your back.

Natural companion

TanStackMarkdown

A serializable document model that keeps highlighting at an explicit boundary.

Explore Markdown

Partners

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

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