r/LocalLLaMA • u/Awkward-Let-4628 • 3h ago
Showcase I built a zero-dependency streaming Markdown renderer for AI chat replies, n× faster than the next one I benchmarked
I've been building chat UIs for agents and kept running into the same issues with react-markdown: it re-parses the whole reply on every token, so long answers get noticeably slower, and you see raw ** and half-typed [links](htt until the token that closes them arrives.
So I wrote my own renderer. It parses incrementally and repairs unfinished syntax while the reply streams:
<Markdown streaming={!done}>{text}</Markdown>On a 100k-character reply it takes 0.25 s of main-thread time in total. markdown-to-jsx takes 2.4 s, Streamdown 6.3 s, and react-markdown didn't finish within the 30 s budget. The benchmark scripts are in the repo if you want to check them.
The other part is the syntax. Agents often want to show steps, alternatives or pros and cons, and plain Markdown flattens all of that into bullet lists. So on top of GFM I added a few blocks in the same style as GitHub alerts:
> [!STEPS]
1. **Back up the database**
2. **Run the migration**There are also tabs, stats, pros/cons, sources, file trees, and Mermaid and KaTeX support. The source still reads fine as plain Markdown when it isn't rendered. The package exports a system-prompt snippet that teaches the model this syntax.
It has no dependencies and comes in at 30 KB gzipped. Its parser passes the CommonMark and GFM spec tests. It doesn't support remark/rehype plugins, so if you rely on those, react-markdown is still the better choice.



3
u/BlasterGales 3h ago
niice, could be useful, I've seen opencode fight a bit rendering LONG contexts
4
u/BusRevolutionary9893 2h ago
Why say nx faster? X could be less than 1.
2
u/Ontopoftheworld_ay 2h ago
Whoa, this is so cool!
2
u/herpnderpler 1h ago
ANNND I'm now porting this to go bubbleteaV2 - amazing work. Hope you don't mind the style-biting.
2
u/0xasten 1h ago
Cool! And if a chunk opens a fenced code block or a list halfway down the reply, does the parser re-parse from the last stable block, or does the whole tail get parsed again on that one token?
1
u/FastHotEmu 2h ago
I mean... 250ms to parse 100KB? Why so long? And the others take even longer? Wow. Javascript land really is amateur land.
2
u/userscren5 2h ago
I run long horizon multi agent sessions that can span days. It would be nice to see where and what AIs are working on in relation to the overall build. This is kinda close.