Repository navigation
stream-chat-react v15.0.0
v15 rebuilds the React SDK on stream-chat v10. Components read their state from the client's state stores and paginators instead of React contexts that copied channel state. Layout and navigation are now composable slots. Every message, composer and channel-list surface can be customized through action sets and component slots. The release also adds a new AI components entry point, an i18n layer with typed keys, and a tree-shakeable ESM build.
Important
v15 requires stream-chat@^10.0.0 and has many breaking changes. Before you upgrade, read the v14 → v15 migration guide. Every break is listed in the breaking changes reference, and the translation changes have their own i18n migration guide. Because v15 also moves to stream-chat v10, follow the stream-chat v9 → v10 guide as well.
✨ Highlights
Built on stream-chat v10 state
ChannelStateContext,ChannelActionContextandTypingContexthave been removed. Components now read from the client's stores: useuseChannel()for the channel,useMessagePaginator()for messages, anduseStateStore(channel.state, selector)for any other channel state.MessageListandVirtualizedMessageListget their messages from(thread ?? channel).messagePaginator. This covers jumping to a message or to the first unread message, loading in both directions, and the unread snapshot.ChannelListis driven by aChannelPaginatorregistered withclient.channelManager. Ordering, filtering and handling of incoming channels are configured in stream-chat, not throughChannelListprops.- Request handlers for send, update, delete and mark-read are registered once on the client through
client.config. TheChannel/Threadrequest props are gone.
New layout and navigation (stream-chat-react/slot-layout)
ChatViewhas been rebuilt around layout slots. You declareviews,layoutsandslotRenderers, and render open entities with<Slot>,<ChannelSlot>and<ThreadSlot>.- Workspace navigation (
useWorkspaceNavigation(),WorkspaceNavigationProvider,useCloseThread()) handles opening channels and threads from channel lists, search results, thread lists and reply buttons. It works panel-aware insideChatView, and you can provide your own outside it. ChannelandThreadfollow the same pattern: each takes an instance prop and renders its children.Threadno longer needs aThreadProvider, and neither component remounts when its instance changes.- New
stream-chat-react/slot-geometryentry point.
AI components (stream-chat-react/ai-components)
- Agent conversations, reply steps, tool approvals and sign-in flows.
- Generated UI, with A2UI and OpenUI renderers, themed from the AI design tokens. The renderer packages (
@a2ui/*,@openuidev/*) are optional peer dependencies, so you install them only if you use generated UI. - Voice agent visualizations (
VoiceWave,VoiceGlow) anduseHeardTextto pace text with voice output.
Customization
- Action sets everywhere. Message actions are configured with
messageActionSetand each item'sisVisible. The channel members header actions use the same shape (Component,placement: 'dropdown',isVisible). - Composer previews are a configurable set (
defaultMessageComposerPreviewSet). You can also supply the composer used for message edits. - Message UI overrides go through one slot:
MessageUIviaWithComponents. ComponentContextslots are typed by the props they receive. Overrides now apply everywhere the SDK renders that component, including link previews, galleries, quoted messages, poll vote lists and thread list items.- Icons are available as
ComponentContextoverrides.ChannelHeadergets aTitleslot. Channel, thread and list headers takeStartContent/EndContentprops.
Messages and composer
- Messages that are still sending show live upload progress for their attachments.
- Only one voice message plays at a time across the whole app.
- A poll message also renders its text and attachments, with the quoted message above the poll.
- Submit with
messageComposer.send()/update()oruseMessageComposerSubmitFn(). They return'sent' | 'nothing-to-send' | 'failed'. - Failed uploads are retried in place through
AttachmentManager.uploadFile. Voice recordings start with a pending upload state. SimpleAttachmentSelectorand the plain upload button follow the composer's file rules, includingcustomCdn. A newStandaloneButtonis available.- Mention handling is built on mention entities, and
renderText(text, options)takes them throughoptions.messageMentionEntities.
Connectivity
- New
useWSConnectionState()anduseNetworkConnectionState()hooks. - The lost-connection banner tells a socket drop ("Reconnecting…") apart from the device being offline ("Waiting for network…").
i18n
- The translation runtime is shared with React Native through
@stream-io/i18n. - Translation keys are namespaced and type-checked, so
t()is strictly typed. - Only English is bundled, which removes about 112 KB gzip (27%) from the bundle. Register other languages yourself.
Accessibility, performance and platform
ChannelListrenders alistboxwithoptionitems and acceptslistboxProps.ChatView's selector is a navigation landmark witharia-current.- The ESM build emits one module per source file, so bundlers can tree-shake the SDK.
useStateStoreprovidesgetServerSnapshot, so server rendering works.- Local unread counts are supported.
⚠️ Breaking changes
These are the most common changes. The breaking changes reference has all 100+ entries, with a migration for each.
Package
- The
stream-chatpeer dependency is now^10.0.0.dayjsandi18nextare no longer direct dependencies;@stream-io/i18nand@stream-io/state-storeare added. ImportStateStorefrom@stream-io/state-store, and make sure the app resolves only one copy. ChatViewand its helpers moved tostream-chat-react/slot-layout.@stream-io/transliterateis no longer an optional dependency.AIStatesis now exported fromstream-chat. Unused exports were removed:Root,Header,UploadIcon,BinIcon,PauseIconandPlayIcon.- Importing the SDK now types
channel.data.custom.name/.image. Remove your own declarations of these fields onCustomChannelData.
Chat, layout and navigation
Windowis removed.ChatView.Channels,ChatView.ThreadsandChatView.ThreadAdapterare replaced by slots.activeChatViewis renamed toactiveView.ChatContextno longer exposeschannel,setActiveChannel,channelsQueryStateorlatestMessageDatesByChannels. Selecting a channel goes through workspace navigation, and outsideChatViewit does nothing until you provide a navigation.- The
optionsprop ofuseCreateChatClientis nowconfigand takes the stream-chat configuration tree ({ client: { … } }).useChatdropped its i18n params, andChat.defaultLanguageis removed. channelPaginatorsOrchestratoris renamed tochannelManager.
Channel
Channelrequires achannelprop and no longer queries or watches the channel. Callchannel.watch()yourself before rendering it; channels fromChannelListare already watched.initializeOnMount,channelQueryOptionsandgetChannelare removed,EmptyPlaceholderis replaced byChannelPlaceholder, andChannelno longer renders its own loading or error state.Channelno longer marks the channel read on mount (markReadOnMount), no longer writesdocument.title, and no longer reloads on reconnect, because the client reloads activated channels itself. A custom surface that doesn't render<Channel>must callchannel.activate().- The request-handler props (
doSendMessageRequest,doUpdateMessageRequest,doDeleteMessageRequest,doMarkReadRequest) are removed. Register handlers withclient.configunderchannel.requestHandlers/thread.requestHandlers. - The attachment sizing and Giphy props moved from
ChanneltoAttachment.onMentionsClick/onMentionsHovermoved offChannel. useChannelConfigreturns the resolved configuration, so fields are renamed, for exampletyping_events→typingEvents.enabled.
Channel list
ChannelListtakes a requiredpaginator. All query, event and render props are removed, along withChannelListUI,usePaginatedChannelsand the channel-list utilities.ChannelListContextno longer provideschannels,hasNextPage,loadNextPageandsetChannels. OnChannelListItem,lastMessageis renamed topreviewedMessage, the selection props are removed, andlatestMessagePreview/getLatestMessagePrevieware removed.- Some defaults changed: nothing is selected on mount, channels outside the list's filters are not added, and the list scrolls infinitely.
Threads and headers
Threadrequires athreadprop and renders its children. Pass message list and composer props to the children you render.ThreadHeaderonly takesoverrideTitle, and closing goes through workspace navigation.ComponentContext.ThreadHeader,HeaderStartContentandHeaderEndContentare removed; headers takeStartContent/EndContentinstead.ThreadProviderno longer wraps its children in aChannel.
Message lists and messages
MessageListno longer acceptsmessages,hasMore,loadingMoreNewer,jumpToLatestMessage,messageLimit,headorthreadList. Use the paginator, theThreadHeadoverride anduseThreadContext()instead.- The
messageActionsprop,MESSAGE_ACTIONS,OPTIONAL_MESSAGE_ACTIONSandgetMessageActions()are removed. Pass a filtereddefaultMessageActionSetasmessageActionSetinstead. ComponentContext.Messageand theMessageprop are replaced by theMessageUIslot.disableDateSeparatoris nowwithDateSeparatorwith the inverted meaning.noGroupByUser/shouldGroupByUserare nowgroupByUser.groupStylesis nowgetGroupStylesand takes a single object.MessageContextno longer hasendOfGroup,firstOfGroup,groupedByUser,initialMessage,threadList,mutesormessageIsUnread. UsegroupStyles,useIsRenderedAsThreadParent()anduseThreadContext()instead.useUserRoleis renamed touseMessagePermissionsand no longer returnsisAdmin,isModeratororisOwner.disableQuotedMessagesandPinPermissionsare removed.renderText(text, mentionedUsers, options)is nowrenderText(text, options). Mention handlers receive(event, message).VirtualizedMessageListdropsdefaultItemHeight,overscanandscrollSeekPlaceHolder. Pass them throughadditionalVirtuosoPropsinstead.allowConcurrentAudioPlaybackis removed, because playback is always exclusive.
Message composer
overrideSubmitHandler,preventClearingOnUnmount,emojiSearchIndex,parentandhandleSubmitare removed. For emoji autocomplete, registercreateTextComposerEmojiMiddlewarefromstream-chat-react/emojis.useSendMessageFn/useUpdateMessageFnare removed. UsemessageComposer.send()/update()instead, and compare the result to'sent'.- A failed send or edit no longer restores the composer.
useAttachmentManagerState().hasCustomDoUploadRequestis replaced bycustomCdn.
Contexts and customization
- Context hooks no longer take a
componentNameargument, and required contexts throw when used outside their provider. - Slots that the SDK renders without props are typed
React.ComponentTypewithout props.
i18n
- The built-in dictionaries (
de,es,fr,hi,it,ja,ko,nl,pt,ru,tr),isLanguageSupportedandSupportedTranslationsare removed. - Translation keys are now namespaced identifiers instead of the English text. A key map is provided for renaming.
- The
Streami18nAPI has changed:setLanguagereturnsvoidandtis read-only.
Data shapes (from stream-chat v10)
- Custom fields are stored under
custom:channel.data.custom.name,user.custom.*andattachment.custom.duration. - Server timestamps are
TimestampNS(unix nanoseconds), sodayjs(created_at)no longer works on raw values. - Message moderation data is in
message.moderation.
CSS and markup
- The
Window,str-chat__main-panelandstr-chat__containerwrappers are removed. - The theme scope moved to
ChatView. The channel list keeps its own theme scope only when rendered outsideChatView. - The
str-chat__virtual-message__wrapper--*grouping classes andstr-chat__thread--virtualizedare removed. Use.str-chat__li--top|middle|bottom|single.
🐛 Notable fixes
- Message list: keeps the reader's place when older pages load, including on iOS WebKit. The viewport stays still when a jump reaches the latest messages, and the floating date separator no longer stacks on the inline one. The last message stays fully visible in short virtualized lists, and every message that has delivery or read state now shows it.
- Notifications: pin, mute and delete failures show an error notification. Channel and thread errors render in a stable notification host. Channel and thread list query errors show a retry button.
- Attachments and gallery: Giphy attachments render in their own group, videos without a thumbnail play, the selected Giphy version loads, and link preview thumbnails fall back to
thumb_url. - Rendering: markdown is stripped from channel list previews, markdown tables no longer render an empty row, and quotes, locations, polls and the AI stop button use colors that match their bubble.
- Misc: Pin only shows with the
pin-messagecapability, and the share-location dialog keeps a single position watch.VirtualizedMessageListnow passes mention handlers, user handlers andunsafeHTMLto messages, andThreadno longer sends requests on mount.
📚 Migration resources
- AI-assisted migration guide: v14 → v15
- Full breaking changes reference
- i18n migration guide
- stream-chat v10 release notes
Full changelog: v14.12.0...v15.0.0