AI responses do not arrive all at once. They stream token by token, and the interface must render them incrementally without jarring layout shifts, flickering, or false signals of completion. The streaming indicator is the component that communicates: the system is actively generating a response. It is not done yet. Wait.
The traditional approach -- a spinner or a typing indicator with bouncing dots -- fails for AI interfaces because it provides no information about progress. A spinner says "something is happening." A streaming text display says "here is what the system is thinking, and more is coming." The second is dramatically more useful because it lets the user evaluate the response as it forms and interrupt if the system is heading in the wrong direction.
interface StreamingDisplayProps {
tokens: string[]
isComplete: boolean
cursor?: {
visible: boolean
blinkRate: number // ms, typically 500-800
character: string // usually '|' or a block cursor
}
onTokensRendered?: (count: number) => void
}
// The cursor element animates opacity between 1 and 0.
// When isComplete transitions to true, the cursor fades out
// over 200ms rather than disappearing abruptly.
// Content container uses min-height to prevent collapse
// during the brief pause between token batches.
A spinner says something is happening. Streaming text says what is happening. The difference is the difference between waiting and reading.
The key accessibility concern is that streaming content must not trigger screen reader announcements on every token. Use aria-live="polite" on the container and debounce updates so that assistive technology announces meaningful chunks rather than individual words. When streaming completes, announce the full message once.