# Svelte Markdown
> A powerful, customizable markdown and HTML renderer for Svelte 5 — built for rendering streaming AI agent output from Claude Code, ChatGPT, and agentic workflows. Built on Marked and HTMLParser2 with 24 markdown renderers, 83 HTML tag renderers, LRU token caching, allow/deny filtering, and XSS-safe defaults.
## Overview
- Package: `@humanspeak/svelte-markdown`
- License: MIT
- Requires: Svelte 5
- Maintained by: [Humanspeak, Inc.](https://humanspeak.com)
- Current version: see https://www.npmjs.com/package/@humanspeak/svelte-markdown
## Installation
```bash
npm install @humanspeak/svelte-markdown
```
## Basic Usage
```svelte
```
## Streaming AI Agent Output
The library is purpose-built to render LLM streaming output that mixes markdown and HTML — partial nested HTML structures reconcile correctly as `` arrives mid-stream.
```svelte
```
The streaming API supports both append-mode (string chunks) and websocket-style offset chunks (`writeChunk({ value, offset })`). Sanitization runs per token as chunks arrive — a `javascript:` URL or `on*=` handler emitted mid-stream is blocked before it reaches the DOM.
## XSS-Safe Defaults
Built-in sanitization runs in the Parser before tokens reach any renderer or snippet. Applied automatically with no opt-in:
- **URL protocol allowlist** — `href`, `src`, `action`, `formaction`, `cite`, `data`, `poster` restricted to `http:`, `https:`, `mailto:`, `tel:`, and relative URLs. `javascript:`, `vbscript:`, `data:`, and `blob:` are blocked (including mixed-case and leading-whitespace variants).
- **Event handler stripping** — every `on*` attribute (`onclick`, `onerror`, `onload`, etc.) removed.
- **`srcdoc` stripping** — prevents iframe HTML injection.
- **No `
```
## Custom HTML Tag Routing
Route semantic markup like ``, ``, or any custom element to your own Svelte components:
```svelte
```
## Key Features
- AI agent / LLM output rendering — stream mixed markdown and HTML from Claude Code, ChatGPT, Gemini, and agentic workflows
- LLM streaming mode with smart token diffing (median ~3ms per chunk on typical streams, well under the 60fps budget)
- Streaming-aware sanitization — partial HTML blocks reconcile correctly as the closing tag arrives
- XSS-safe defaults — URL protocol allowlist, `on*` and `srcdoc` stripping
- Custom sanitizer hooks — `sanitizeUrl` / `sanitizeAttributes` props with `defaultSanitize*` and `unsanitized*` exports
- 24 built-in markdown renderers (heading, paragraph, link, code, table, etc.)
- 83 HTML tag renderers for raw HTML within markdown
- Custom HTML tag routing — render ``, ``, or any tag as your own component
- Svelte 5 runes compatibility ($props, $derived) with full TypeScript types
- LRU token caching (50-200x faster re-renders)
- Allow/deny filtering for HTML tags and markdown renderers (`allowHtmlOnly`, `excludeHtmlOnly`, `buildUnsupportedHTML`, `allowRenderersOnly`, `excludeRenderersOnly`, `buildUnsupportedRenderers`)
- Custom renderer components and Svelte 5 snippet overrides for inline customization
- First-party marked extensions module — `@humanspeak/svelte-markdown/extensions` exports `markedKatex` + `KatexRenderer`, `markedMermaid` + `MermaidRenderer`, `markedAlert` + `AlertRenderer`, and `markedFootnote` + `FootnoteRef` + `FootnoteSection`
- Code formatting via the `marked-code-format` walkTokens extension — add `prettier` to any code fence and it's auto-formatted through Prettier with zero custom renderer
- Async markdown parsing support
- Secure HTML parsing via HTMLParser2 (no `innerHTML`)
- Standalone `IncrementalParser` export for headless / non-Svelte / server-side consumers (same engine as `streaming={true}`)
## Use Cases
- Streaming chat / assistant UIs (Anthropic SDK, OpenAI SDK, custom SSE)
- Rich AI artifact rendering (design mockups, PR explainers, dashboards) emitted by agents as HTML
- Throwaway editors with copy-back exports — agent emits an HTML editor for one piece of data, user pastes the result back into the next prompt
- Status reports / synthesized explainers — agents emit semi-structured HTML reports with embedded diagrams and tables
- Mixed markdown + custom semantic tags (``, ``, ``)
Canonical docs root: https://markdown.svelte.page/docs
Per-page markdown mirrors: https://markdown.svelte.page/docs/.md
Full reference (single document): https://markdown.svelte.page/llms-full.txt
## Documentation
- [Rendering AI Agent Output](https://markdown.svelte.page/docs/advanced/agent-output.md) — https://markdown.svelte.page/docs/advanced/agent-output
- [Allow/Deny Filtering](https://markdown.svelte.page/docs/advanced/allow-deny.md) — https://markdown.svelte.page/docs/advanced/allow-deny
- [Headless Parser](https://markdown.svelte.page/docs/advanced/headless-parser.md) — https://markdown.svelte.page/docs/advanced/headless-parser
- [LLM Streaming](https://markdown.svelte.page/docs/advanced/llm-streaming.md) — https://markdown.svelte.page/docs/advanced/llm-streaming
- [Marked Extensions](https://markdown.svelte.page/docs/advanced/marked-extensions.md) — https://markdown.svelte.page/docs/advanced/marked-extensions
- [Security](https://markdown.svelte.page/docs/advanced/security.md) — https://markdown.svelte.page/docs/advanced/security
- [Token Caching](https://markdown.svelte.page/docs/advanced/token-caching.md) — https://markdown.svelte.page/docs/advanced/token-caching
- [Tree Shaking](https://markdown.svelte.page/docs/advanced/tree-shaking.md) — https://markdown.svelte.page/docs/advanced/tree-shaking
- [SvelteMarkdown Component](https://markdown.svelte.page/docs/api/svelte-markdown.md) — https://markdown.svelte.page/docs/api/svelte-markdown
- [Types & Exports](https://markdown.svelte.page/docs/api/types.md) — https://markdown.svelte.page/docs/api/types
- [Examples](https://markdown.svelte.page/docs/examples.md) — https://markdown.svelte.page/docs/examples
- [Basic Rendering](https://markdown.svelte.page/docs/examples/basic-rendering.md) — https://markdown.svelte.page/docs/examples/basic-rendering
- [Custom Renderers Examples](https://markdown.svelte.page/docs/examples/custom-renderers.md) — https://markdown.svelte.page/docs/examples/custom-renderers
- [HTML Filtering Examples](https://markdown.svelte.page/docs/examples/html-filtering.md) — https://markdown.svelte.page/docs/examples/html-filtering
- [Inline Rendering](https://markdown.svelte.page/docs/examples/inline-rendering.md) — https://markdown.svelte.page/docs/examples/inline-rendering
- [Linked Headings Examples](https://markdown.svelte.page/docs/examples/linked-headings.md) — https://markdown.svelte.page/docs/examples/linked-headings
- [Parsed Callback](https://markdown.svelte.page/docs/examples/parsed-callback.md) — https://markdown.svelte.page/docs/examples/parsed-callback
- [Snippet Overrides Examples](https://markdown.svelte.page/docs/examples/snippet-overrides.md) — https://markdown.svelte.page/docs/examples/snippet-overrides
- [Getting Started](https://markdown.svelte.page/docs/getting-started.md) — https://markdown.svelte.page/docs/getting-started
- [Migration Guide](https://markdown.svelte.page/docs/migration.md) — https://markdown.svelte.page/docs/migration
- [Custom Renderers](https://markdown.svelte.page/docs/renderers/custom-renderers.md) — https://markdown.svelte.page/docs/renderers/custom-renderers
- [HTML Renderers](https://markdown.svelte.page/docs/renderers/html-renderers.md) — https://markdown.svelte.page/docs/renderers/html-renderers
- [Markdown Renderers](https://markdown.svelte.page/docs/renderers/markdown-renderers.md) — https://markdown.svelte.page/docs/renderers/markdown-renderers
- [Snippet Overrides](https://markdown.svelte.page/docs/renderers/snippet-overrides.md) — https://markdown.svelte.page/docs/renderers/snippet-overrides
## Links
- Homepage:
- Repository:
- NPM:
- Issues:
- Background reading: [Using Claude Code: The Unreasonable Effectiveness of HTML](https://x.com/trq212/status/2052809885763747935) by Thariq