# Markstream

> Multi-framework streaming Markdown renderer for AI chat apps, supporting Vue, React, Svelte, Angular, Nuxt, and Next.js with Mermaid, KaTeX, and stream-diffs code blocks.

Markstream is an open-source family of streaming Markdown renderers purpose-built for AI chat interfaces, LLM token streams, and SSE/WebSocket output. Created by Simon He, the project is licensed under MIT and hosted on GitHub with nearly 3,000 stars. It ships separate framework packages — `markstream-vue`, `markstream-react`, `markstream-svelte`, `markstream-angular`, and `markstream-vue2` — all sharing the same core rendering model.

## What It Is

Markstream solves a specific problem that general-purpose Markdown renderers like `marked`, `markdown-it`, or `react-markdown` do not address well: rendering Markdown that is still arriving while the user is reading it. When an LLM streams tokens over SSE or WebSocket, a naive renderer re-renders the entire tree on each update, causing flicker and memory spikes. Markstream instead uses incremental batching and a virtual window strategy to keep updates smooth and memory usage predictable, even for 50 KB+ AI responses.

## How the Rendering Model Works

Markstream offers two core rendering strategies per surface:

- **Virtual window (default):** Keeps `max-live-nodes` at 220 by default, enabling a sliding window of mounted elements. Long documents stay responsive without skeleton placeholders.
- **Incremental batching:** Setting `:max-live-nodes="0"` disables virtualization and enables a typewriter-style effect, governed by `batchRendering`, `renderBatchSize`, `renderBatchDelay`, and `renderBatchBudgetMs` props.

The renderer accepts either raw Markdown strings via the `content` prop or pre-parsed node trees via the `nodes` prop (produced by `parseMarkdownToStructure`), enabling SSR/worker pre-parsing with deterministic hydration on the client. A `final` prop signals end-of-stream, forcing unclosed constructs like code fences or math delimiters to settle rather than remain in a perpetual loading state.

## Framework and Integration Coverage

All six framework packages share the same core rendering model and are actively developed:

- **Vue 3 / Nuxt / VitePress** — `markstream-vue`, the most fully documented path
- **React / Next.js / Remix** — `markstream-react`, with a migration guide from `react-markdown`
- **Svelte 5** — `markstream-svelte`
- **Angular standalone** — `markstream-angular`
- **Vue 2.6 / 2.7** — `markstream-vue2`
- **Framework-agnostic parsing** — `stream-markdown-parser`
- **Streaming controller utilities** — `markstream-core`

Optional heavy peers — `mermaid`, `katex`, and `stream-diffs` — are not bundled and load on demand. Progressive Mermaid rendering lets diagrams appear as soon as syntax is available and improve with later updates. The `stream-diffs` runtime powers an enhanced `CodeBlockNode` surface with File/Diff rendering and syntax highlighting; without the peer, the renderer falls back to plain `<pre>` output.

## Key Features

- Streaming-first incremental rendering with minimal re-renders and low-jitter DOM updates
- Two render modes: virtual window for long documents, incremental batching for typewriter effects
- Progressive Mermaid diagram rendering with graceful fallback
- `stream-diffs` File/Diff code block surface with syntax highlighting and diff interactions
- KaTeX math rendering with optional Web Worker offloading
- Custom component registration via `setCustomComponents` (global or scoped by `custom-id`)
- Custom HTML tag allowlist for trusted tags like `<thinking>`
- Safe HTML policy with `htmlPolicy="escape"` for untrusted user content
- SSR-compatible imports for Vite, Nuxt, and VitePress
- TypeScript-first with complete type definitions
- YAML front matter extraction and mapping to custom tags
- CDN-backed worker injection for KaTeX and Mermaid without bundler peers

## Update: markstream-vue 2.0 and markstream-vue2 2.0.4

The 2.0 stable line is the current `latest` npm tag. It removes the Monaco and `stream-markdown` code-block runtimes and consolidates enhanced code block rendering under `stream-diffs` as the only supported surface. The 1.x line remains available via `markstream-vue@1` and the `legacy` npm tag. The most recent release listed in the GitHub repository is `markstream-vue2@2.0.4`, published on 2026-08-24. The repository was last pushed on 2026-08-26, indicating active ongoing development. A migration guide from 1.x to 2.0 is available in the documentation.

## Features
- Streaming Markdown rendering for AI/LLM token streams
- Virtual window rendering for long documents (50KB+)
- Incremental batching typewriter mode
- Progressive Mermaid diagram rendering
- stream-diffs File/Diff code block surface
- KaTeX math rendering with Web Worker support
- Custom component registration (global and scoped)
- Custom HTML tag allowlist (e.g., thinking tags)
- Safe HTML policy for untrusted content
- SSR-compatible imports for Vite, Nuxt, VitePress
- Pre-parsed node rendering via parseMarkdownToStructure
- SSE and WebSocket streaming support
- YAML front matter extraction
- CDN-backed worker injection for KaTeX and Mermaid
- TypeScript-first with complete type definitions
- Smooth streaming with configurable batch size and delay
- Dark mode support via .dark class or :is-dark prop
- Scoped CSS under .markstream-vue container

## Integrations
Vue 3, Nuxt, VitePress, React, Next.js, Remix, Svelte 5, Angular, Vue 2, Mermaid, KaTeX, stream-diffs, markdown-it-ts, Tailwind CSS, SSE (Server-Sent Events), WebSocket, Vite, StackBlitz

## Platforms
WEB, API, DEVELOPER_SDK, CLI

## Pricing
Open Source

## Version
markstream-vue2@2.0.4

## Links
- Website: https://markstream.simonhe.me
- Documentation: https://markstream.simonhe.me/guide/
- Repository: https://github.com/Simon-He95/markstream-vue
- EveryDev.ai: https://www.everydev.ai/tools/markstream
