<!-- Source: https://markdown.svelte.page/compare/vs-svelte-streamdown -->
<!-- Canonical: https://markdown.svelte.page/compare/vs-svelte-streamdown -->
# Svelte Markdown vs Svelte Streamdown

Two Svelte 5 Renderers Built for AI Streaming

## Overview

Compare svelte-streamdown and @humanspeak/svelte-markdown: two Svelte 5 markdown renderers for streaming AI output, with different approaches to styling, caching, HTML, MDX, and rich content.

- **Svelte Markdown site:** https://markdown.svelte.page
- **Svelte Markdown npm:** https://www.npmjs.com/package/%40humanspeak%2Fsvelte-markdown
- **Svelte Markdown slug:** svelte-markdown
- **Category:** Streaming Markdown Renderer
- **Approach:** Reactive content prop with cached block splitting and block-level reuse
- **Website:** https://svelte-streamdown.beynar.workers.dev
- **GitHub:** https://github.com/beynar/svelte-streamdown
- **npm:** https://www.npmjs.com/package/svelte-streamdown

## Feature comparison

| Feature | @humanspeak/svelte-markdown | Svelte Streamdown | Notes |
| --- | --- | --- | --- |
| Svelte 5 Compatibility | Yes | Yes |  |
| TypeScript Support | Yes | Yes |  |
| Streaming API | Reactive source or direct writeChunk() ingestion | Reactive complete-content prop | Svelte Markdown can consume transport deltas directly. With Svelte Streamdown, the application maintains and repeatedly supplies the accumulated content string. |
| Out-of-Order Chunk Delivery | Native offset-addressed chunk assembly | No | Svelte Markdown accepts writeChunk({ value, offset }) and assembles websocket-style chunks even when they arrive out of order. Svelte Streamdown accepts a complete content string, so callers must order and assemble chunks before updating the prop. |
| Mid-Stream Corrections | Offset writes can replace earlier ranges | Caller rebuilds the content string | Offset-addressed writes support retransmission, transcription correction, and edits to previously received output without requiring callers to reconstruct the complete document first. |
| Stream Lifecycle Isolation | resetStream() + streamId | Caller-managed content state | Svelte Markdown provides synchronous resetStream() and declarative streamId boundaries to prevent content from one response carrying into the next. |
| Incomplete Markdown | Yes | Yes | Both projects are designed to keep partial AI output renderable while new content arrives. |
| Streaming HTML Output | Partial blocks reconcile when </tag> arrives | Incomplete blocks handled | Svelte Markdown explicitly tracks incomplete raw HTML tails; Svelte Streamdown documents graceful handling for incomplete markdown and MDX blocks. |
| Repeated Document Cache | Built-in configurable LRU + TTL | No | Svelte Streamdown caches block splitting and uses Svelte reactivity to reuse unchanged mounted blocks, but does not provide a reusable LRU for completed documents that are revisited or remounted. |
| Append-Only Stream Reuse | Tail-window parser + frame coalescing | Cached block splitting + reactive block reuse | Both avoid needlessly parsing stable content. Svelte Markdown additionally coalesces bursts of incoming updates at the animation-frame boundary. |
| Measured Streaming Performance | 2–4× faster under burst backpressure | Effectively tied when updates are frame-paced | Production Chromium benchmark against svelte-streamdown 3.1.2. Across 10–200 KB append-only streams, Svelte Markdown completed burst workloads in roughly half to one quarter of the time by coalescing updates per animation frame. At one 512-character update per frame over 50 KB, both sustained about 59 updates/second. The 50 KB output used 2,821 descendant elements with Svelte Markdown versus 3,480 with Svelte Streamdown. Reproduce with pnpm perf:stream-compare. |
| Measured DOM Footprint (50 KB) | 2,821 descendant elements | 3,480 descendant elements | Measured by the production Chromium streaming benchmark with animations and optional rich-content controls disabled. The difference reflects each renderer’s output structure; Svelte Streamdown’s additional presentation features may justify that structure for applications that use them. |
| Custom Renderers | 24 markdown + 83 HTML snippet overrides | Typed snippets + theme system |  |
| HTML Tag Control | 83 tags with allow/deny helpers | skipHtml + allowed element controls |  |
| URL Safety Defaults | Protocol allowlist + attribute sanitization | Configurable prefixes (allow all by default) | Svelte Streamdown exposes link and image prefix controls; their documented default is ["*"]. |
| Streaming Animations | No | Word, character, or block animations |  |
| MDX-Style Components | No | Yes |  |
| Inline Citations | No | Popover + list/carousel views |  |
| Built-in Styling | Unstyled by default | Tailwind typography + themes |  |
| Math (KaTeX) | Opt-in first-class extension | Opt-in component |  |
| Diagrams (Mermaid) | Opt-in first-class extension | Opt-in interactive component |  |
| Code Highlighting | Opt-in Shiki extension | Opt-in Shiki component + copy button |  |
| Marked Extensions | Full extension objects | Custom tokenizers |  |
| Advanced Tables | GFM tables | GFM + row/column spans, footers, multiple headers |  |

## Svelte Markdown strengths

- Svelte 5 runes-native — built for runes, not retrofitted
- TypeScript-first with full type safety
- Built-in token caching (50-200x faster re-renders on repeated content)
- LLM streaming with imperative writeChunk() / resetStream() API
- 24 markdown renderers + 83 HTML tag renderers — every override is a Svelte snippet
- First-class extensions: KaTeX math, Mermaid diagrams, GitHub alerts, footnotes
- Opt-in Shiki syntax highlighting (streaming-compatible, tree-shaken from core)
- Built-in XSS protection — protocol allowlist, event-handler stripping, attribute sanitization
- Allow/deny utilities (allowHtmlOnly, excludeRenderersOnly, etc.) for fine-grained control
- Drop-in component — works anywhere in your Svelte app
- Direct transport-delta ingestion without maintaining a second reactive accumulator
- Native out-of-order chunk assembly with offset-addressed writes
- Mid-stream replacement writes for corrections and retransmission
- Explicit resetStream() and streamId lifecycle boundaries
- Measured 2–4× faster than svelte-streamdown 3.1.2 under burst backpressure
- Measured about 19% fewer descendant elements on the 50 KB benchmark
- Configurable LRU cache also accelerates repeated non-streaming documents
- Broad raw HTML support with per-tag renderers and allow/deny helpers
- Stricter URL and attribute sanitization enabled by default
- Unstyled core integrates without requiring Tailwind

## Svelte Streamdown strengths

- Purpose-built streaming animations at word, character, and block level
- MDX-style custom Svelte components inside runtime markdown
- Interactive citations with popover, list, and carousel presentations
- Opinionated typography and granular Tailwind theme system out of the box
- Rich built-ins including interactive Mermaid controls, code copy buttons, and advanced tables

## Svelte Markdown limitations

- Smaller community (newer project)
- Runtime-only (no build-time optimization)
- No built-in token reveal animations or citation UI
- No MDX-style component syntax inside markdown
- Requires application styling by design

## Svelte Streamdown limitations

- No imperative chunk-ingestion API — callers update the complete content string
- No native offset-addressed assembly for out-of-order chunks or earlier-range corrections
- Stream resets and response isolation are managed in caller-owned content state
- No reusable LRU cache for switching among previously rendered documents
- Link and image prefix controls allow all origins by default
- Opinionated styling requires Tailwind setup or theme overrides
- A newer, single-maintainer port that tracks the upstream React project

## Verdict

Choose Svelte Streamdown when you want a batteries-included AI response UI with animated reveals, citations, MDX-style components, interactive diagrams, and Tailwind styling. Choose @humanspeak/svelte-markdown when you want a lower-level, unstyled renderer with direct and out-of-order chunk ingestion, explicit stream lifecycle controls, frame-coalesced updates, reusable document caching, broad raw-HTML customization, and stricter security defaults. Both are credible Svelte 5 choices for incomplete streaming markdown; the deciding factor is whether you want an opinionated presentation layer or a composable rendering primitive.

## Keywords

svelte-streamdown, svelte streamdown, svelte-streamdown vs svelte-markdown, svelte streaming markdown, svelte ai markdown renderer, streamdown svelte
