Skip to the library
The AI chat UI library · 2026

The AI chat
interface library.

A comprehensive, organized reference for the people building AI chat - five categories, the patterns inside each, and the trade-offs and motion specs that govern them. Drawn from Anthropic, OpenAI, Perplexity, Raycast, and Vercel. Every pattern runs live.

01category · 2 patterns

Input states & architectures

Where the prompt lives, and how it accepts more than text. The first decision a chat product makes, and the one users feel on every turn.

Docked vs command palette

#input#navigation#shortcuts
ChatGPTRaycastSpotlight

A bar docked to the bottom edge anchors a persistent thread; a Spotlight or Raycast-style palette summoned with Command+K floats over the work and acts in context. The choice is a wager about where attention should sit.

Docked
Always present, anchors a continuous thread, high discoverability.
Palette
Summoned on demand, acts on context, returns focus when dismissed.
Triggers
Intent-driven shortcuts surface the right action without a menu dive.
document.tsx

live specimen · interact with it

in the wild

search files⌘K
Results
Search FilesCommand
Clipboard HistoryExtension
Open Recent ProjectNavigation
AI ChatAI
RaycastOpen
Raycast's command palette - a summoned, centered input with ranked results.Raycast

Tip · Anchor the palette high and centered, dim the backdrop, and make the first result actionable on Enter.

Trade-off matrix - cognitive load, efficiency, scalability

dimensionBottom-dockedCommand palette
Cognitive load
always visible
recall the verb
Efficiency (power users)
reach for it
one keystroke
Scalability of actions
bar gets crowded
searchable list
Discoverability
visible affordance
hidden behind ⌘K
Context preservation
thread scrolls
acts on selection

↓ lower is better. Dock for sustained dialogue; palette for sharp, scalable, contextual commands.

Multi-modal input

#input#voice#image#file
ChatGPTClaude

Text is one channel of several. Voice capture, image paste, and file drops all funnel into the same composer - the craft is absorbing each modality without the bar becoming a control panel.

Voice
A live waveform and timer make capture legible; one tap to stop.
Drop zone
The whole surface accepts a drag; the target lights on dragover.
Attachments
Chips above the bar - removable, named, never blocking the input.
input.multimodalready

Speak, drop an image, or attach a file

Message, or use voice / attachments

live specimen · interact with it

in the wild

Drop to attach · report-q3.pdf
mockup.png
Describe the attached screenshot…
File drops and context-aware inputs - attachments resolve into named chips.ChatGPT / Claude

Tip · Let the whole surface accept a drop; lift attachments into removable chips above the bar, never inside it.

02category · 3 patterns

Message rendering & components

A message is a layout problem, not a string. Reasoning, structured output, citations, and feedback each need their own treatment inside the turn.

Reasoning blocks & feedback

#message#reasoning#feedback
ClaudeDeepSeek

Collapsible thought blocks expose the model's reasoning the way DeepSeek and Claude do, then fold so the answer leads. Inline controls let you copy, regenerate, and rate without leaving the turn.

Thought blocks
Reasoning streams in, then auto-collapses once the answer starts.
System notes
A quieter register that frames the turn without competing with it.
Feedback loop
Copy, regenerate, and thumb up / down, revealed on completion.
messagethinking

System · Support agent. Refund window is 30 days. Exceptions allowed at the agent's discretion.

It's been 31 days but I never got my confirmation. Can I still get a refund?

The user wants a refund but it's day 31 of a 30-day window. Policy is firm, but the delay was on our side - the confirmation email bounced. I'll approve it as a goodwill exception and say why, so it doesn't read as a loophole.

live specimen · interact with it

in the wild

Claude
Is 31 days too late for a refund?
Thought for 4 seconds

The window is 30 days, so this is past policy.

But the confirmation email bounced - that's on us.

I'll approve a goodwill exception and explain why.

I've approved your refund as a one-time exception, since our confirmation never reached you. It'll post in 3-5 business days.
Claude's expandable 'thought' section - reasoning folded above the answer.Claude

Tip · Stream the reasoning while thinking, then auto-collapse it the instant the answer starts so the result leads.

Friction vs delight - managing density

add friction

Fold reasoning by default

A 200-word trace above every answer is noise. Collapse it, stream a one-line summary, and let curiosity decide when it opens.

add delight

Auto-collapse on completion

Expand the thought block while thinking, then fold it once the answer starts. The motion tells the user the work is done.

hold the line

Controls on demand

Reveal copy and feedback only after the turn finishes. Mid-stream they are dead weight competing with the text that matters.

Structured output

#message#artifacts#canvas
ClaudeChatGPT

Tables, code, and documents render either inline in the thread or split into a side-by-side artifact pane. Short and glanceable stays inline; long or editable earns its own canvas.

Inline
Renders in the bubble - best for short, read-only output.
Side-by-side
Opens a pane so the thread stays scannable while you edit.
The rule
Length and editability decide; don't bury a long artifact in the stream.
structured.output

Compare the three plans in a table.

Here's the breakdown - the table renders directly in the thread:

PlanPriceSeatsHistory
Free$017 days
Pro$205Unlimited
Team$6020Unlimited

good for short, glanceable output

live specimen · interact with it

in the wild

Chat
Build a pricing card.
Opened it in the panel so you can edit it live.
PricingCard.tsx
Artifacts
Studio
$24
Start trial
Claude's Artifacts - the generated work lives in a side-by-side pane.Claude

Tip · Split long or editable output into its own pane and keep a link back to it in the thread.

ChatGPT
Draft a launch post.
Opened a canvas - edit inline and I'll revise.
Canvas · launch-post.md
Introducing Studio
ChatGPT's Canvas - an editable document surface for writing and code.ChatGPT

Tip · Treat the canvas as the source of truth; let chat suggest edits that apply back into the document.

Citations & source cards

#message#trust#sources
Perplexity

Perplexity's model: inline numbered markers sit flush with the clause they support, and each resolves to a source card. Citations turn a confident paragraph into a checkable one.

Inline markers
Numbered chips on the clause, not bolted onto the end.
Source cards
Title, domain, and number; hover or tap to link the two.
Hover link
Activating a marker highlights its card, and vice versa.
answer.citedready

live specimen · interact with it

in the wild

What makes a reasoning UI trustworthy?
Sources3
nngroup.com
arxiv.org
acm.org
Trust comes from showing the work1 and citing each claim inline2, so a reader can verify rather than take it on faith3.
Perplexity's citations and source cards - every claim links to its source.Perplexity

Tip · Show the source cards before the prose, then cite them inline so each claim resolves to a card.

03category · 2 patterns

Streaming physics & motion

The signature motion of chat. Cadence, easing, cursor, and reveal strategy decide whether generation reads as thinking or as buffering.

Token vs block streaming

#motion#streaming
ChatGPTClaude

Token streaming reveals the answer word by word - the user reads as the model writes. Block streaming holds each paragraph until whole, then reveals it as a unit: calmer, but a longer first wait. A thinking pulsar covers the gap before the first output.

Token
Lowest perceived latency; the wait becomes the content.
Block
Calmer cadence; reveal whole paragraphs with a soft ease.
Pulsar
A pulsing dot bridges the silence before the first token lands.
stream.mode
thinking
0 / 38 tokens

live specimen · interact with it

Trade-off matrix - token vs block

dimensionToken-by-tokenBlock-level
Perceived latency
first word fast
wait for whole block
Visual calm
constant motion
settles per block
Layout stability
needs reserved height
fewer reflow points
Fit for rich content
tables/code flicker
render once, whole

↓ lower is better. Token for prose and speed; block for structured or richly formatted output.

Typewriter physics

#motion#cursor#specs
ChatGPTClaude

The variables are concrete: token cadence, easing curve, cursor behaviour, and whether the layout holds steady as tokens land. Tune them and feel the difference.

Cadence
Uneven timing with rare pauses reads as cognition, not a metronome.
The cursor
A caret that snaps on / off with steps(), never fades.
No layout shift
Reserve the final height so streaming never reflows the page.
response.streamready

Explain what makes a streaming response feel alive.

Scroll into view to begin…

00 / 50 tokens

live specimen · interact with it

in the wild

Thinking
Generating

A streaming response feels alive because text arrives the way a thought forms, in uneven bursts

Thinking and generation states - the cursor and cadence that signal life.ChatGPT / Claude

Tip · Bridge the pre-token silence with a pulsar, then hand off to a steady caret the moment text starts.

Motion engineering - streaming specs

Token entry

cubic-bezier(0.2, 0, 0, 1)

per token · 18-28ms

Block reveal

cubic-bezier(0.16, 1, 0.3, 1)

240-320ms ease-out

Caret pulse

cubic-bezier(0.4, 0, 0.6, 1)

1000ms · steps cadence

Typewriter cadence
base 26ms + rand(34ms) + 12% chance(+240ms)jitter and the rare pause are what read as thought
Caret
0.5ch bar · 1s steps(1) blink · accent fillsteps(), not ease - a real caret snaps, never fades
Anti layout-shift
render full text invisible; absolute-position the stream over itreserves final height so the page never reflows token-by-token
Reduced motion
skip cadence · paint final state · disable blinkhonour prefers-reduced-motion on every streaming surface
Compositor only
animate transform / opacity / filternever width / height / top - they trigger layout each frame
04category · 2 patterns

State, history & memory

Conversations aren't linear and context isn't infinite. Branching, context budgets, and pinned memory all need to be visible to be trusted.

Threading & branching

#state#history#branching
ChatGPTClaude

Editing an earlier prompt forks the thread into parallel branches you can step between - one chat holding every version you tried. The hard part is making the active branch unmistakable.

Edit in place
Reveal an edit affordance on a past turn; the change is non-destructive.
Branching
Each edit forks a branch; a compact switcher steps between them.
The detail
The downstream reply cross-fades on switch, never snaps.
threadbranch 1 of 3

Draft a welcome note for new members.

Here's a warm, friendly welcome note you can send the moment someone joins.

Make it more formal.

1/3

Certainly. Here is a revised version written in a measured, professional register suitable for external stakeholders.

try editing →

live specimen · interact with it

Visual logic for branching

hold the line

One active path, always legible

Render only the active branch in full; collapse siblings into a counter. The thread reads as one conversation, not a tree to parse.

add delight

Cross-fade the fork point

When the branch changes, cross-fade everything downstream. A hard swap implies a new chat; a fade says "same conversation, different choice."

Context window & memory

#state#memory#context
ClaudeChatGPT

A finite budget, made visible. The window bar shows what's consuming context - system, pinned memory, conversation - and pinning protects what matters when older turns get evicted.

Window bar
A segmented gauge of the budget, colour-coded by source.
Pinned memory
Global context that survives eviction of older turns.
Eviction
Drop the oldest unpinned turn when the budget runs tight.
context.windowhealthy
context used15.9k / 32k tokens · 50%
SystemPinned memoryConversation
  • System prompt1.2k
  • Pinned: brand guide3.4k
  • Turn 1 - 45.2k
  • Turn 5 - 86.1k
pinned segments survive eviction

live specimen · interact with it

05category · 2 patterns

Interactive delight & friction

Assistance is leverage. Suggest well and the interface anticipates the user; over-suggest and it becomes noise. Complex agent states need disclosure, not exposure.

Suggestions & quick replies

#delight#suggestions#follow-ups
ChatGPTClaude

Ghost text completes the prompt as the user types, quick-reply chips collapse a fork into one tap, and follow-ups are generated from the answer rather than a static menu. Suggestion is leverage - spend it carefully.

Inline suggestion
Ghost text proposes the line; Tab accepts, typing ignores it.
Quick replies
Short, dynamic chips for the obvious next answers.
Follow-ups
Derived from this answer, never a generic list.
composetyping

live specimen · interact with it

Friction vs delight - assistance budget

add delight

Predict, don't interrupt

Ghost text sits inline at low contrast and yields instantly to a keystroke. A shortcut, never a block.

add friction

Cap the chip count

Three quick replies clarify; seven paralyse. Each chip is a decision you're asking for - spend them only on real forks.

hold the line

Earn the follow-up

Follow-ups must derive from this answer. A generic "Tell me more" trains users to ignore the row.

Progressive disclosure

#delight#agents#disclosure
ClaudePerplexity

A complex agent run, summarized to one line per phase. Detail lives behind a tap, so an eight-step task reads as three lines until the user asks for more - density without overwhelm.

Phase summary
One legible line per phase; status by icon and motion.
Disclose on tap
Expand a phase to reveal its sub-steps - never a wall of logs.
Live status
A spinner on the active phase; checks accrue as it completes.
agent.stateready

A complex agent run, summarized to one line per phase. Tap a phase to disclose its steps - detail on demand, never a wall of logs.

live specimen · interact with it

the substrate every pattern shares

Structural foundations

Patterns differ; the substrate doesn't. These are the structural rules every chat surface in this library is built on - the numbers that keep it aligned, legible, and tappable across viewports.

Optical alignment

Asymmetric icons
nudge ±1px toward visual centersend arrows, carets and play triangles read off-center when geometric
Icon + label lockup
match weight, size, and optical baselinebalance the pair, not the bounding boxes
Bubble radii
outer = inner + padding (concentric)tail corner tightened to rounded-br-md / rounded-bl-md
Hairlines
tint borders toward the surface hueblack/8 light · white/7 dark - present, never harsh

Mobile-first touch targets

Minimum target
≥ 44 × 44px (coarse pointer)expand the hit area with a pseudo-element, keep the paint small
Icon controls
size-9 (mobile) → size-7 (≥sm)fingers first; precise pointers reclaim the space
Input font size
≥ 16px on mobileanything smaller triggers iOS focus-zoom
No double-tap delay
touch-action: manipulationapplied globally to every control

Typography hierarchy

Display
Exposure · EXPO -10 · ≥ 1.5rem onlyhero, category and pattern heads, big numerals
Body & UI
OpenRunde 400 / 500the workhorse for every message and label
Specs & meta
JetBrains Monocode values, eyebrows, tags, counters
Fluid scale
clamp(1.9rem, 6vw, 3rem)headings track the viewport without breakpoint jumps

Conversational padding

Page gutter
20px (mobile) → 32px (≥sm)px-5 → sm:px-8, no horizontal overflow at any width
Bubble padding
14px × 10px (px-3.5 py-2.5)consistent across user and assistant turns
Inter-turn rhythm
12-16px between turnstight enough to read as one thread, loose enough to scan
Category rhythm
6rem (mobile) → 9rem (≥sm)generous air between categories; the page breathes