/

UI Kits for AI Apps: Composers, Transcripts and States

Five surfaces general component libraries do not carry, the streaming problems that only appear after the first token, and the three things no kit gives you.

Serafim Korablev
Serafim Korablev
@korablev

Building the interface for an AI product is not building a chat window. It is building five surfaces that general component libraries do not carry: a composer that handles attachments and streaming, a transcript that renders partial markdown without flickering, a tool-call display, a citation format, and the set of states between "thinking" and "failed".

Below is where each of those lives, and why the usual advice to "just use a component library" does not survive contact with the first token.

The composer

The most-used surface in any AI product and the one with the most requirements. It grows as you type, sends on Enter and newlines on Shift-Enter, holds attachments, exposes a model picker, and turns into a stop button while a response is streaming.

AI Chat Input by preetsuthar17 and v0 AI Chat by kokonutd are the prompt-first versions, where the composer is the whole landing surface. AI Input With Loading is the one that carries its own status message, and AI Voice Input is the recording state.

The implementation detail that matters: auto-resize by measuring scrollHeight on every keystroke forces a layout on every keystroke. Use field-sizing: content where it is available, cap the height, and keep the send button reachable when the textarea is tall.

The transcript

Chat Message List by jakobhoeg is the scrolling container, Expandable Chat is the widget form, and Message Dock by Isaiah is the compact one.

Two problems specific to streaming. Autoscroll has to stop the moment the reader scrolls up, or reading anything while a response arrives is impossible; the usual approach is to pin to the bottom only while the reader is already within a few pixels of it. And markdown arrives incomplete: a half-written code fence or a lone asterisk will re-render as different elements on every token unless the parser is told to tolerate unterminated blocks.

The states

An AI response has more states than a request. Queued, thinking, streaming, tool-running, complete, refused, failed, cancelled. Most interfaces ship three and leave the reader guessing at the rest.

Message loading by jakobhoeg is the in-transcript indicator, and the loading guide covers why a shimmer beats a spinner once text has started to arrive. The rule worth taking: the state belongs in the transcript, not over it, because an overlay hides the thing the reader is waiting to read.

The multimodal surfaces

Audio Chat by Jatin Yadav and IA Siri Chat by S.dev are the voice interfaces, AI Chat Image Generation by gonzalo chalé is the image-output transcript, and AI Assistant Interface by Rafael Porto is the assembled assistant panel.

Voice adds a requirement that text does not: a visible, always-available way to stop. A model that keeps talking after the reader has stopped listening is the AI equivalent of an autoplaying video.

What no kit gives you

Three things you will build regardless, and they are the ones that decide whether the product feels trustworthy.

Tool calls the reader can follow. When the model searches, runs code or calls an API, showing that as a collapsed step with a name and a result is the difference between a system that appears to be working and one that appears to be stalled.

Citations that survive the answer. If the response quotes a source, the link has to be in the transcript rather than in a footnote the streaming replaced. This is also what makes an AI answer verifiable, which is the same standard the testimonial guide applies to a quote.

A refusal that is not an error. "I cannot help with that" is a normal outcome, not a failure state, and rendering it in red with a retry button teaches the reader the product is broken.

Where else to look

The honest list, because the answer is not always us:

SourceBest forTrade-off
AI SDKThe streaming, tool-call and state machinery underneathNot a design system; the visuals are yours
shadcn/uiEvery primitive the surfaces are built fromNothing AI-shaped at all
Kokonut UIThe strongest set of AI input surfaces in one registryMarketing-shaped elsewhere
21stComposers, transcripts, voice panels and loading statesQuality 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:

bash

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. The 21st MCP covers the same ground without leaving the editor: ask Claude, Cursor or Codex for a chat surface, get the previews inline, and let the agent write the file.

Browse AI chat components →

Frequently asked

What does an AI product need that a component library does not have?
Five surfaces: a composer that grows and handles attachments and streaming, a transcript that renders partial markdown without flickering, a tool-call display, a citation format, and the states between thinking and failed. General libraries carry none of them, because they are shaped for forms and marketing pages.
Why does my streaming markdown flicker?
Because incomplete markdown parses differently on every token. A half-written code fence or a lone asterisk re-renders as a different element each time. Use a parser configured to tolerate unterminated blocks, and hold the last stable render rather than re-parsing from scratch on every chunk.
How should autoscroll behave in a chat transcript?
Pin to the bottom only while the reader is already within a few pixels of it, and stop the moment they scroll up. Unconditional autoscroll makes it impossible to read anything while a response arrives, which is exactly when people want to read the earlier part of the answer.
What states does an AI response need?
More than a request: queued, thinking, streaming, tool-running, complete, refused, failed and cancelled. Most interfaces ship three. In particular a refusal is a normal outcome and not an error, and rendering it in red with a retry button teaches the reader the product is broken.

Published

Aug 20, 2026

Read time

6 min

Tags

GuideAIReactChat

Share