Table of Contents
For frontend apps consuming streaming LLM responses, well-built abstractions matter for UX. The React (or framework-equivalent) patterns are mature in 2026; standard libraries handle most cases.
Use useChat from Vercel AI SDK or equivalent. Handles SSE parsing, abort, optimistic UI, error states. UX patterns: typing indicator while waiting first token, streaming text reveal, abort button mid-generation, copy-on-complete. Standard React; hides streaming complexity; keep frontend code clean.
React hook
import { useChat } from '@ai-sdk/react';
export default function Chat() {
const { messages, input, handleInputChange, handleSubmit, isLoading, stop } = useChat({
api: '/api/chat',
});
return (
<div>
{messages.map(m => <div key={m.id}>{m.role}: {m.content}</div>)}
<form onSubmit={handleSubmit}>
<input value={input} onChange={handleInputChange} />
{isLoading && <button onClick={stop}>Stop</button>}
</form>
</div>
);
}
UX patterns
- Typing indicator while waiting for first token (~150-500ms TTFT)
- Streaming text reveal as tokens arrive
- Abort button visible during generation
- Final state with copy / regenerate buttons after generation completes
- Error state with retry option on failure
- Markdown rendering as text streams (incremental rendering)
Verdict
For React frontends consuming streaming LLM responses, Vercel AI SDK's useChat hook is the standard primitive. Handles SSE complexity; provides clean state for UI. For other frameworks (Vue, Svelte), equivalent libraries exist. Don't roll your own SSE parsing — the abstractions are mature.
Bottom line
useChat hook handles streaming UX. See streaming server.