A typing indicator answers one question - is something coming - and it answers it in a way no spinner can, because it says who. In a chat between people it means a person is composing. In a chat with a model it means tokens are on the way. Those look identical and mean different things, and the second one has an obligation the first does not.
The components
Typing Indicator by ddoemonn is the bouncing three-dot bubble, Typing by loading-ui is the vertical-bounce variant, and Message loading by jakobhoeg is the version built for a transcript, which the AI kit guide covers as part of the states an AI response passes through.
The typing animation is a different component with the same name: Typing Effect by Shatlyk1011 and Typing Animation by dillionverma type text out character by character. The animated text guide argues that belongs in a terminal or a chat and not in a headline, where the reader is waiting for information you already have.




Where it goes
In the transcript, in the position the message will occupy. Not floating over it, not in a corner, not as a status line above the composer.
The reason is layout: an indicator that sits where the message will appear means nothing jumps when the message arrives. One that lives elsewhere produces a shift at exactly the moment the reader starts reading, which the loading guide names as the most common loading mistake.
The three details
Announce it, once. A live region saying "Assistant is typing" or "Sarah is typing" is what makes the indicator exist for a screen reader. Use polite, and do not re-announce on every dot cycle: announce on appearance and on disappearance, not continuously.
Cap it. A person can stop typing without sending, and a model call can fail. An indicator with no timeout is a promise that never resolves. Ten to fifteen seconds, then fall back to a neutral state or an error, per the empty state guide on the difference between waiting and broken.
Reduced motion. Bouncing dots are motion. Under prefers-reduced-motion: reduce, show a static three-dot bubble or the text alone. The information survives; the bounce does not need to.
The honesty question, for AI
An indicator in a human chat reports a fact: someone is typing. In an AI product it is easy to make it report an intention instead - showing "thinking" while a request queues, or animating during a wait that has nothing to do with generation.
That is a small lie with a compounding cost, because the reader calibrates on it. If the model has not started, say queued. If a tool is running, say which. The AI kit guide lists the states worth distinguishing, and the reason to distinguish them is that a system whose progress reporting is accurate is a system whose other claims get believed.
Where else to look
The honest list, because the answer is not always us:
| Source | Best for | Trade-off |
|---|---|---|
| Three spans and a CSS keyframe | The whole indicator, honestly | You write the live region |
| A shimmer | Streaming text that has already started | Different signal: arriving, not awaited |
| 21st | Bubbles, transcript-shaped indicators and typing effects | Quality varies by author, so preview before you take it |
Taking one
Every component page has a live preview and the code. Installing goes through the shadcn CLI against our registry:
That key comes from your 21st account, and installs require a membership. Set API_KEY_21ST once in your shell and the command works for anything in the catalogue.
Frequently asked
- Where should a typing indicator appear?
- In the transcript, in the position the message will occupy, so nothing jumps when the message arrives. An indicator floating above the composer or in a corner produces a layout shift at exactly the moment the reader starts reading.
- How do you make a typing indicator accessible?
- Announce it once in a polite live region, on appearance and on disappearance rather than on every dot cycle. Under prefers-reduced-motion, show a static bubble or the text alone: the information survives without the bounce.
- Does a typing indicator need a timeout?
- Yes. A person can stop typing without sending and a model call can fail, so an indicator with no cap is a promise that never resolves. Ten to fifteen seconds, then a neutral state or an error.
- What is the honesty problem with AI typing indicators?
- It is easy to animate during a wait that has nothing to do with generation, showing thinking while a request queues. Readers calibrate on that, so say queued when it is queued and name the tool when one is running. Accurate progress reporting is what makes the system's other claims believable.



