Scrim UI

Streaming Markdown UIPro

Markdown that renders correctly while it is still arriving — bold, code spans, links and tables settle without ever flashing raw syntax or reflowing.

markdownstreamingmessagerendering
Pro

The implementation stays private

This public build contains the product description, API shape and production guidance, but not a second copy of the paid component. Pro members can inspect, copy and install the complete source below.

Component source

Single-file React + Tailwind component, no dependencies. Included with Pro — the source and its install command unlock together.

533 lines of source, included with Pro

The preview above is the real component. Pro unlocks its source, the shadcn install command, and every other Pro item — $49 once.

When to use it

  • Pass `streaming` straight from the SDK's status — it drives correctness, not just a caret. Finished text must be parsed strictly, because an unmatched `**` in a completed message is two literal asterisks.
  • Render this instead of swapping renderers at the end of a turn. Swapping reflows the whole message at the moment the reader is furthest down it.
  • Keep the message container a fixed width. Speculation removes reflow from inside the text; a container that resizes with content puts it back.
  • Use it for the assistant turn only. User messages are complete the moment they exist and have nothing to speculate about.

What breaks in production

  • Leaving `streaming` on after the turn ends — trailing asterisks or backticks in the final text then render as formatting the author never wrote.
  • Re-parsing the whole message on every token. Blocks above the last boundary cannot change; parsing them once is the difference between smooth and stuttering at a few thousand tokens.
  • Rendering an ambiguous fragment rather than holding it. A lone `#` or a pipe row with no separator yet can still become several different things, and correcting it on screen is the flicker you were trying to remove.
  • Letting a partly-arrived table row set the column count — every subsequent cell then shifts sideways as the row fills.

Related Components