useStream via the useExternalStoreRuntime adapter.
How it works
- Stream with
useStream— connect to your agent and get reactive messages, loading state, and submit/cancel callbacks - Adapt with
useExternalStoreRuntime— bridgestream.messagesinto assistant-ui’s runtime format by convertingBaseMessage[]toThreadMessageLike[] - Provide the runtime — wrap your UI in
AssistantRuntimeProviderand render any assistant-ui thread component
Installation
Wiring useStream
TheuseExternalStoreRuntime adapter bridges stream.messages into the assistant-ui runtime. Pass it to AssistantRuntimeProvider and render any thread component:
Converting messages
toThreadMessages maps LangChain BaseMessage[] to the ThreadMessageLike[] format assistant-ui expects. Handle each message type — human, AI, and tool — and convert content blocks, tool calls, and reasoning tokens:
Customising the thread UI
<Thread /> ships a complete default thread UI including message list, composer, and scroll management. Customise individual parts by overriding component slots:
Best practices
- Memoise message conversion: wrap
toThreadMessages(stream.messages)inuseMemoto avoid re-running the conversion on every render - Handle attachments: use
CompositeAttachmentAdapterwithSimpleImageAttachmentAdapterfor image uploads; extend with custom adapters for files - Use branching: assistant-ui has built-in message branching support via
MessageBranch; edit a message to regenerate from that point - Thread persistence:
useStreamwithfetchStateHistory: trueandreconnectOnMount: truegives assistant-ui access to the full thread history on page load
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

