How should you design loading and streaming states for AI responses?
Design AI loading states as a sequence of distinct, named states instead of one spinner. A language model request can wait in a queue, spend seconds reasoning, stream text, call tools and fail at any of those points. Users tolerate the wait far better when the screen tells them which of those is happening.
Traditional loading design assumes a fast, predictable request: show a skeleton, swap in the content. AI requests are slower and less predictable, and the output arrives in pieces. That changes the job. Our general guide to loading states, skeletons and optimistic UI covers the fast case. This one covers the AI case, and it sits inside our wider hub on AI product UX.
One principle runs through everything below: say what the system is doing in the user's words, not the model's. Users don't care about tokens. They care about whether it's working and how long it'll be.
What are the distinct AI loading states?
There are six AI states worth designing separately: queued, thinking, streaming, tool running, done and failed. Each one answers a different question for the user, so each needs different copy and a different visual signal.
State | User's question | Visual | Example copy |
|---|---|---|---|
Queued | Did it receive my request? | Message sent, subtle pulse | Starting... |
Thinking | Is it working on it? | Animated indicator with a label | Thinking through your question |
Tool running | What is it doing right now? | Named step with an icon | Searching your help center |
Streaming | Is the answer coming? | Text appears with a cursor | No label needed; the text is the signal |
Done | Can I use this now? | Cursor gone, actions enabled | Optional: Answered from 4 sources |
Failed | What went wrong and what now? | Inline error with retry | That took too long. Try again or shorten the request. |
You won't always show all six. A simple rewrite feature might jump from queued to streaming to done. An agent that searches, reads and writes will cycle through tool running several times. Design all six once in your component library, then let each feature use what it needs.
How do you design an AI thinking indicator?
An AI thinking indicator should show that work is happening and, where possible, what kind of work. A bare animated dot tells users the screen hasn't frozen, but it doesn't tell them whether to wait five seconds or a minute.
- Pair motion with a label. Animated dots or a shimmer plus a short line such as Thinking through your question.
- Update the label as stages change. Moving from Reading the contract to Checking clause 4 shows progress without fake percentages.
- Don't invent a progress bar. Model response time isn't predictable, so a bar that stalls at 90% does more harm than a named stage.
- Let users peek at reasoning, optionally. Some products show a collapsible summary of reasoning steps. Keep it collapsed by default; most users want the answer, not the working.
How should streaming response UI work?
Streaming response UI should render text the moment it arrives, keep the layout stable while it grows, and hold back actions until the stream ends. Streaming is the best answer to LLM latency UX because the first words appear quickly, even when the full answer takes much longer.
Reserve space and pin the scroll
Start the response container at a sensible height and only auto-scroll if the user is already at the bottom. If they scroll up to reread, stop following the stream.
Show a cursor, not a spinner
A blinking cursor or soft fade at the end of the text says more is coming. Remove it when the stream completes so done is visible.
Render formatting progressively
Tables, lists and code blocks should form cleanly as they stream, not flash raw symbols and then snap into shape. This is an engineering decision as much as a design one.
Disable risky actions until done
Copy, insert, send and approve should wait for the full answer. A half-streamed reply pasted into an email is a support ticket waiting to happen.
Offer stop, and keep what arrived
A visible stop button lets users cut off a long or wrong answer. Keep the partial text on screen and label it as stopped.
If you're building this in React, our guide to building AI features in a web app covers the streaming plumbing behind these patterns.
How do you show tool use and multi-step progress?
Show tool use as a short, readable list of named steps, each with a status: running, done or failed. When an AI calls search, reads files or hits an API, users want to know what it touched, both to judge the answer and to catch it doing something they didn't expect.
Name steps by outcome, not function. Searched 3 documents in Billing is clear. Called search_kb is not. Collapse completed steps into a one-line summary once the answer starts streaming, and let users expand it if they want to check what was used. For agents that take real actions, such as sending messages or editing records, the step list becomes an action log, and it needs approvals and undo. Our guide to agentic UX covers that next level.
Example step copy for a research assistant
For example, suppose a research assistant answers a question about refund policy. The step list could read: Understanding your question (done). Searching help center, 12 articles (done). Reading 3 most relevant articles (done). Writing answer (streaming). Once streaming starts, the list collapses to Used 3 help center articles, with each article linked.
If one step fails, show it in place: Couldn't open Refunds 2024.pdf, answer uses the other 2 articles. That's honest, specific and lets the user decide whether to trust the result.
What should AI failure and timeout states say?
AI failure states should say what happened, keep the user's input, and offer a next step. The worst failure state is a blank response or a generic Something went wrong that wipes the prompt the user spent time writing.
Failure | Copy that works | Action |
|---|---|---|
Timeout | This is taking longer than usual. | Keep waiting or Try again |
Rate or usage limit | You've reached today's limit. It resets at 9:00. | See plans or wait |
Tool failed | Couldn't reach your calendar. Answer is based on email only. | Retry calendar |
Content refused | I can't help with that request. Here's what I can do instead. | Suggested alternatives |
Unknown error | Something broke on our side. Your message is saved. | Try again |
Failures that aren't really errors, like a weak or uncertain answer, belong to a different set of patterns. Our guide to AI error handling UX covers hallucinations, low-confidence answers and recovery.
How do you turn AI states into reusable components?
Turn AI states into a small set of shared components so every AI feature behaves the same way. When the thinking indicator, step list, streaming container and error banner are built once, users learn them once, and your team stops redesigning loading for every new feature.
In practice that means a status component that takes a state and a label, a step list that accepts named steps with statuses, a streaming text container with stop and copy controls, and an inline error with retry. Document the copy rules next to the components, since the words matter as much as the animation. Our guide to design systems for AI products goes deeper on the component set. We design and build these states together, words and code in the same team, which is usually where generic spinners get replaced.
