Step 2 / 5
Ship a streaming chat UI
Build a complete chat interface with streaming — without a backend.
`useChat` wires state, streaming, abort, and retries. Drop it into any component. The preview below runs a mock adapter. Try it: send a message, watch it stream.
Try it live
Hi, ask me something.
Source
import { useChat, ChatContainer, Message, InputBar } from '@agentskit/react'import '@agentskit/react/theme'import './styles.css'// Mock adapter — streams fake replies. Swap for `anthropic({ apiKey })`, `openai({ apiKey })`,// or any adapter from @agentskit/adapters in your own app.const FAKE = [ 'Welcome to AgentsKit. Streaming is on by default.', 'Swap the adapter in one line to change providers.', 'Tools and memory are optional — compose what you need.',]let turn = 0const mockAdapter = { createSource: () => ({ async *stream() { const reply = FAKE[turn++ % FAKE.length] for (const ch of reply) { await new Promise((r) => setTimeout(r, 18)) yield { type: 'text', content: ch } } yield { type: 'done' } }, abort() {}, }),}export default function App() { const chat = useChat({ adapter: mockAdapter, initialMessages: [ { id: 'init', role: 'assistant', content: 'Hi, ask me something.', status: 'complete' }, ], }) return ( <div style={{ display: 'flex', flexDirection: 'column', height: '100vh', fontFamily: 'system-ui' }}> <ChatContainer className="ak-chat"> {chat.messages.map((msg) => ( <Message key={msg.id} message={msg} /> ))} </ChatContainer> <InputBar chat={chat} /> </div> )}