Components / Text & motion

StreamText

Streaming text: reveals characters quickly like a token stream, resolves the leading edge out of a soft blur, and keeps a caret that blinks once the text settles.

Install

npx shadcn@latest add https://irisui.dev/r/stream-text.json
import { StreamText } from "@/components/iris/stream-text/stream-text";
Registry item stream-textBrings in foundationRegistry JSON

Preview

StreamText

Streams text in: reveals characters quickly like a token stream, resolves the leading edge out of a soft blur, and keeps a caret that blinks once the text settles.

When to use

  • Rendering an assistant reply, a rewrite suggestion or a generated summary as it "arrives".
  • Any text surface that should feel live — it inherits typography from its context, so it drops into chat bubbles, cards and selection actions.
  • For a status label while work is still running, use Shimmer or TextShimmer. For a one-time headline entrance, use TextReveal.

Usage

import { StreamText } from "@/components/iris/stream-text/stream-text";

<p className="reply">
  <StreamText key={reply.id} text={reply.text} charsPerTick={2} tickMs={9} onDone={() => setSettled(true)} />
</p>;

Props

Prop Type Default Description
text string — Full text to stream (required). A new string restarts the stream.
charsPerTick number 2 Characters revealed per tick — higher is faster.
tickMs number 9 Interval between reveals, in ms.
blurTail number 6 How many trailing characters carry the soft blur edge.
caret boolean true Render the caret: solid while streaming, blinking once idle.
className string — Class on the wrapping span.
onProgress () => void — Fires each tick — useful for re-anchoring UI to reflowing text.
onDone () => void — Fires once the full string is shown.

Notes

  • It simulates streaming from a complete string; to render real tokens as they arrive, pass the growing string or remount with a key.
  • The partially streamed text is in the DOM as it reveals; wrap the container in a polite live region only if the reply should be announced, and consider announcing once on onDone instead.
  • Styles live on the component: the tail is a 1.6px blur with a fading mask, the caret is a 2px --ink bar with the animate-stream-text-caret-blink keyframes. Under reduced motion the tail blur is removed and the caret stops blinking; the character reveal itself still runs, so lower tickMs or render the full text directly if that matters.