Streaming Mermaid and KaTeX
AI models increasingly output Mermaid diagrams and KaTeX math in their responses. Rendering these during streaming — not after the response is complete — creates a better user experience.
Progressive Mermaid rendering
When an LLM streams a Mermaid diagram, Markstream renders it incrementally:
Chunk 1: ```mermaid
Chunk 2: flowchart LR
Chunk 3: Input --> Parser
Chunk 4: Parser --> Renderer
Chunk 5: Renderer --> Output
Chunk 6: ```At each chunk, Markstream parses the available Mermaid syntax and renders a partial diagram. The user sees the diagram taking shape rather than waiting for the closing fence.
Setup
pnpm add markstream-vue mermaidimport { setMermaidWorker } from 'markstream-vue'
import MermaidWorker from 'markstream-vue/workers/mermaidParser.worker?worker&inline'
setMermaidWorker(new MermaidWorker())Configuration
<MarkdownRender
:content="streamingContent"
:final="isDone"
:mermaid-props="{
theme: isDark ? 'dark' : 'default',
}"
/>Streaming KaTeX math
KaTeX math ($inline$ and $$block$$) appears during streaming:
Chunk 1: The formula is $
Chunk 2: The formula is $E = mc
Chunk 3: The formula is $E = mc^2$Markstream detects partial math blocks and defers rendering until the expression is complete, avoiding KaTeX errors.
Setup
pnpm add markstream-vue kateximport { setKaTeXWorker } from 'markstream-vue'
import KatexWorker from 'markstream-vue/workers/katexRenderer.worker?worker&inline'
import 'katex/dist/katex.min.css'
setKaTeXWorker(new KatexWorker())Why workers matter
Mermaid and KaTeX are CPU-intensive. Running them in Web Workers:
- Keeps the main thread responsive during streaming
- Prevents UI jank when diagrams re-render on each chunk
- Enables parallel rendering of multiple diagrams
Without workers, parsing a complex Mermaid diagram can block the UI for 50-200ms — noticeable during streaming.
Framework-specific worker setup
React
import { setKaTeXWorker, setMermaidWorker } from 'markstream-react'
import KatexWorker from 'markstream-react/workers/katexRenderer.worker?worker&inline'
import MermaidWorker from 'markstream-react/workers/mermaidParser.worker?worker&inline'
setMermaidWorker(new MermaidWorker())
setKaTeXWorker(new KatexWorker())Svelte
<script lang="ts">
import { setMermaidWorker, setKaTeXWorker } from 'markstream-svelte'
import MermaidWorker from 'markstream-svelte/workers/mermaidParser.worker?worker&inline'
import KatexWorker from 'markstream-svelte/workers/katexRenderer.worker?worker&inline'
setMermaidWorker(new MermaidWorker())
setKaTeXWorker(new KatexWorker())
</script>Angular
import { setKaTeXWorker, setMermaidWorker } from 'markstream-angular'
import KatexWorker from 'markstream-angular/workers/katexRenderer.worker?worker'
import MermaidWorker from 'markstream-angular/workers/mermaidParser.worker?worker'
setMermaidWorker(new MermaidWorker())
setKaTeXWorker(new KatexWorker())Optional peers
Mermaid, KaTeX, Monaco, D2, and Infographic are optional peers. Install only what your AI output needs:
# Only Mermaid (no math)
pnpm add mermaid
# Only KaTeX (no diagrams)
pnpm add katex
# Both
pnpm add mermaid katex
# All heavy peers
pnpm add mermaid katex stream-monaco @terrastruct/d2 @antv/infographicAfter installing a peer, Markstream's default loader can resolve it automatically. enableMermaid() and enableKatex() are for re-enabling or replacing optional dependency loaders; setMermaidWorker() and setKaTeXWorker() inject off-thread worker clients. If a peer is not installed or a loader is disabled, that feature falls back instead of rendering through Mermaid or KaTeX.