vercel

streamdown

A drop-in replacement for react-markdown, designed for AI-powered streaming.

by vercel

TypeScript

TypeScript87.6%
MDX10.6%
HTML1.1%
CSS0.5%
JavaScript0.2%

Commit activity

Last 12 weeks · 92 commits

Full graph →

Community health

5 of 6 standards met

Community profile →
100
✓README✓License✓Contributing✓Code of Conduct○Issue Template✓PR Template

Recent PRs & issues

Active · Last activity 1h ago
See all on GitHub →
nishilfaldu

Stacked on #670 and #685.** Only the last two commits are new: perf(streamdown): repair only the end of a streaming message and fix(streamdown): repair the whole message where remend reads all of it. Please review those commits. The commit before it is #685, adapted to #670. I'll rebase onto once both merge. Description On every streaming update, Streamdown runs remend over the whole message, plus three regex checks for footnotes and link definitions. So each update costs more than the one before. With #670 and #685, remend only completes syntax in the last block. For example, it adds the closing to . It does not change the blocks before it. So the repair of those blocks is wasted work. This PR repairs only the end of the message: the last two blocks. already treats at least the last two blocks as still open, and never reuses them from its cache. Streamdown remembers where the blocks before them end (the stable length) and does not repair that text again. The three checks scan only the end of the text. In a 20,000-token answer sent 8 tokens per update, the last update repairs 128 characters instead of 84,840: Type of Change [x] Performance improvement Related Issues Depends on #670 and #685. Repairing only the end gives the same output as repairing everything only when remend completes syntax in the current block alone. #670 does this for bold and italic, #685 for links. The changeset check fails on #670's changeset, as it does on #670 itself. Changes Made New . Each message keeps a stable length: the end of every block except the last two. Later updates repair only the text after it, and put the kept text in front. The stable length moves forward only on an update where remend changed nothing. Two texts exist on each update: the text the model sent, and the repaired text. Streamdown splits the repaired text into blocks. Remend can add a closer that the block parser reads as a new block. For example, after and a newline, it adds `$\(\[$$$$\rhandlersparseMarkdownIntoBlocksFnallowedTagsliteralTagContentlib/parse-blocks.tsxstream-repair.test.tsinlineKatexpnpm changeset`) [x] All my commits are signed Changeset [x] I have created a changeset for these changes

nishilfaldu · 23h ago
sleitor

Description Replaces physical Tailwind direction utilities with logical ones so layout mirrors under / . Follow-up to #411 (automatic RTL direction support). Type of Change [x] Bug fix (non-breaking change which fixes an issue) Related Issues Closes #642 Changes Made Blockquote: → Lists: → Table header cells, link button, mermaid/table dropdown items: → Code line numbers: → Language label: → (code block header and mermaid) Controls/dropdowns: → , → (code block, image download, link modal, mermaid fullscreen/pan-zoom, table copy/download dropdowns) Kept physical: nothing else physical remained (no / patterns were touched) Updated existing tests asserting old classes; added changeset Testing [x] All existing tests pass ( in packages/streamdown: 1242 passed) [x] Added new tests for the changes (updated blockquote/table/pan-zoom class assertions) [ ] Manually tested the changes (ultracite) clean Checklist [x] I have created a changeset ()

sleitor · 6h ago
sebxt

What happens** When a tag listed in wraps multi-line content that contains a fenced code block, every blank line inside the code block is shown as the literal text `const a = 1;const b = 2;preprocessCustomTagspackages/streamdown/lib/preprocess-custom-tags.ts\n\n\n\n` so the tag is not split into separate blocks. The replacement does not skip fenced code, where an HTML comment is not markup but literal text. A blank line inside a fence cannot end the surrounding HTML block anyway, so it does not need the placeholder.

sebxt · 7h ago
sebxt

Description replaces blank lines in multi-line custom tag bodies with `allowedTagsreplaceBlankLineslib/preprocess-custom-tags.tsreplacestreamdown__tests__/preprocess-custom-tags.test.ts__tests__/custom-tags-markdown.test.tsxmainstreamdownpnpm checkpnpm changeset`) [ ] All my commits are signed Changeset [x] I have created a changeset for these changes Additional Notes No documentation change is needed; this restores the expected rendering of code inside custom tags. Fixes #683

sebxt · 7h ago
Structured data for AI agents

Repository: vercel/streamdown. Description: A drop-in replacement for react-markdown, designed for AI-powered streaming. Stars: 5713, Forks: 315. Primary language: TypeScript. Languages: TypeScript (87.6%), MDX (10.6%), HTML (1.1%), CSS (0.5%), JavaScript (0.2%). Homepage: https://streamdown.ai Topics: ai, markdown, streaming. Latest release: streamdown@2.7.1 (1d ago). Open PRs: 24, open issues: 18. Last activity: 1h ago. Community health: 100%. Top contributors: haydenbleasel, sleitor, farnabaz, aradhyacp, dependabot[bot], 2hu12, molebox, FranciscoMoretti, withkarann, github-actions[bot] and others.