by humanspeak
📝 Markdown and HTML renderer for Svelte 5 — built for streaming AI agent output from Claude Code, ChatGPT, and agentic workflows. XSS-safe defaults, token caching, TypeScript types.
# Add to your Claude Code skills
git clone https://github.com/humanspeak/svelte-markdownGuides for using ai agents skills like svelte-markdown.
Last scanned: 5/30/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-05-30T16:59:11.697Z",
"npmAuditRan": false,
"pipAuditRan": true
}See how svelte-markdown compares with popular alternatives.
svelte-markdown is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by humanspeak. 📝 Markdown and HTML renderer for Svelte 5 — built for streaming AI agent output from Claude Code, ChatGPT, and agentic workflows. XSS-safe defaults, token caching, TypeScript types. It has 142 GitHub stars.
Yes. svelte-markdown passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/humanspeak/svelte-markdown" and add it to your Claude Code skills directory (see the Installation section above).
svelte-markdown is primarily written in TypeScript. It is open-source under humanspeak on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh svelte-markdown against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
A powerful, customizable markdown renderer for Svelte with TypeScript support. Built as a successor to the original svelte-markdown package by Pablo Berganza, now maintained and enhanced by Humanspeak, Inc.
on* handler stripping)extensions prop (e.g., KaTeX math, alerts)HighlightedCode renderer and your choice of engine (Shiki or TanStack Highlight) — streaming-compatible, tree-shaken out of the core bundlewriteChunk({ value, offset }) assembles chunks in any arrival order and keeps rendering while gaps fillVersion 2.0 rebuilds the streaming engine. Component props and the writeChunk() / resetStream() API are unchanged, and most apps only need the version bump. Two behaviors changed:
raw, text, items, header, or rows.code renderer emits one text node per line, so code.firstChild is the first line only. textContent and innerHTML are unchanged.Read the 2.0 upgrade guide for the full list, including streaming output fixes and the new IncrementalParser fields.
Upgrading with an AI assistant? Paste this so it reads the right sources first:
I am upgrading @humanspeak/svelte-markdown from 1.x to 2.0 in a Svelte 5 project.
Before changing anything, read these sources:
- Upgrade guide: https://markdown.svelte.page/docs/migration/v2.md
- Documentation index for LLMs: https://markdown.svelte.page/llms.txt
- Full documentation text: https://markdown.svelte.page/llms-full.txt
- Streaming behavior: https://markdown.svelte.page/docs/advanced/llm-streaming.md
- Direct parser use: https://markdown.svelte.page/docs/advanced/headless-parser.md
- Release notes: https://github.com/humanspeak/svelte-markdown/releases
Then search my codebase for:
1. Custom renderers or snippets used inside lists and tables that read raw,
text, items, header, or rows from props.
2. Code that reads firstChild or childNodes of rendered <code> elements or of
the markdown container.
3. Direct IncrementalParser usage.
4. Tests that snapshot streamed output mid-stream.
List each place that needs a change, explain why using the guide, and propose
the smallest fix.
npm i -S @humanspeak/svelte-markdown
Or with your preferred package manager:
pnpm add @humanspeak/svelte-markdown
yarn add @humanspeak/svelte-markdown
<script lang="ts">
import SvelteMarkdown from '@humanspeak/svelte-markdown'
const source = `
# This is a header
This is a paragraph with **bold** and <em>mixed HTML</em>.
* List item with \`inline code\`
* And a [link](https://svelte.dev)
* With nested items
* Supporting full markdown
`
</script>
<SvelteMarkdown {source} />
Modern AI coding agents — Claude Code, Codex, agentic workflows — increasingly emit HTML alongside markdown for richer output (design mockups, dashboards, reports, interactive artifacts). @humanspeak/svelte-markdown is built for this:
javascript: URLs and on* handlers stripped from agent output before render, no opt-in required (see Security)streaming is enabled, each token is sanitized as it's emitted; mid-tag partials buffer until well-formed, so progressive HTML from an LLM renders without flicker<tool-call>, <thinking>, or your own design-system tags to your own components via renderers.html (see Custom HTML Tags)<script lang="ts">
import SvelteMarkdown from '@humanspeak/svelte-markdown'
import type { StreamingChunk } from '@humanspeak/svelte-markdown'
let markdown: { writeChunk: (chunk: StreamingChunk) => void } | undefined
async function streamFromAgent(response: Response) {
const reader = response.body!.getReader()
const decoder = new TextDecoder()
while (true) {
const { done, value } = await reader.read()
if (done) break
markdown?.writeChunk(decoder.decode(value, { stream: true }))
}
}
</script>
<SvelteMarkdown bind:this={markdown} source="" streaming />
For background on why HTML has become a common agent output format, see Thariq's post: Using Claude Code: The Unreasonable Effectiveness of HTML. For the full streaming API (offset chunks, reset, websocket patterns), see LLM Streaming below.
The package is written in TypeScript and includes full type definitions:
import type {
Renderers,
Token,
TokensList,
SvelteMarkdownOptions,
MarkedExtension
} from '@humanspeak/svelte-markdown'
You can import renderer maps and helper keys to selectively override behavior.
import SvelteMarkdown, {
// Maps
defaultRenderers, // markdown renderer map
Html, // HTML renderer map
// Keys
rendererKeys, // markdown renderer keys (excludes 'html')
htmlRendererKeys, // HTML renderer tag names
// Utility components
Unsupported, // markdown-level unsupported fallback
UnsupportedHTML // HTML-level unsupported fallback
} from '@humanspeak/svelte-markdown'
// Example: override a subset
const customRenderers = {
...defaultRenderers,
link: CustomLink,
html: {
...Html,
span: CustomSpan
}
}
// Optional: iterate keys when building overrides dynamically
for (const key of rendererKeys) {
// if (key === 'paragraph') customRenderers.paragraph = MyParagraph
}
for (const tag of htmlRendererKeys) {
// if (tag === 'div') customRenderers.html.div = MyDiv
}
Notes
rendererKeys intentionally excludes html. Use htmlRendererKeys for HTML tag overrides.Unsupported and UnsupportedHTML are available if you want a pass-through fallback strategy.These helpers make it easy to either allow only a subset or exclude only a subset of renderers without writing huge maps by hand.
buildUnsupportedHTML(): returns a map where every HTML tag uses UnsupportedHTML.allowHtmlOnly(allowed): enable only the provided tags; others use UnsupportedHTML.
'strong' or tuples like ['div', MyDiv] to plug in custom components.excludeHtmlOnly(excluded, overrides?): disable only the listed tags (mapped to UnsupportedHTML), with optional overrides for non-excluded tags using tuples.buildUnsupportedRenderers(): returns a map where all markdown renderers (except html) use Unsupported.allowRenderersOnly(allowed): enable only the provided markdown renderer keys; others use Unsupported.
'paragraph' or tuples like `['p