Design & UI
Render streaming LLM markdown safely in a chat UI with Streamdown: incomplete-token handling, a custom component map, and matching a strict design contract.
1 file
Description
Render streaming LLM markdown safely in a chat UI with Streamdown: incomplete-token handling, a custom component map, and matching a strict design contract.
Displaying assistant messages that arrive token by token and contain markdown (headings, lists, code fences). Plain react-markdown re-parses the whole string every token and flickers or mis-renders half-open syntax mid-stream.
Streamdown is built for text that is still arriving: it handles an unterminated code fence, a half-written table, or an incomplete link without collapsing the layout on every keystroke. Render the accumulated text directly:
import { Streamdown } from "streamdown";
import remarkGfm from "remark-gfm";
<Streamdown remarkPlugins={[remarkGfm]} components={MARKDOWN_COMPONENTS}>
{text}
</Streamdown>
Streamdown renders default HTML elements. In a system with square corners, hairline borders, and no gradients, pass a components map so every element matches instead of shipping library defaults:
const MARKDOWN_COMPONENTS = {
a: (props) => <a className="underline underline-offset-2" {...props} />,
code: (props) => <code className="bg-neutral-100 px-1 font-mono text-[0.9em]" {...props} />,
pre: (props) => <pre className="border border-black/10 bg-neutral-50 p-3 overflow-x-auto" {...props} />,
};
isStreaming && !text so an empty assistant bubble does not sit blank before the first token.key) throws away its incremental work and reintroduces flicker. Keep a stable key and change only the children.javascript: URLs. Constrain or sanitize the a handler.Related
Added 2026-07-01. Back to the Skill Library.

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.