MessageComposer

MessageComposer provides UI and functionality for composing messages (attachment picker, commands, mentions, autocomplete). It must be rendered inside Channel.

Best Practices

  • Render MessageComposer inside Channel to ensure composer state is available.
  • Customize via Channel props first to keep behavior consistent.
  • Keep additionalTextInputProps stable to avoid re-renders.
  • Respect cooldowns and permissions to prevent invalid sends.
  • Use built-in components for attachments and audio before rolling your own.

General Usage

import { StreamChat } from "stream-chat";
import {
  Chat,
  Channel,
  MessageList,
  MessageComposer,
  OverlayProvider,
} from "stream-chat-react-native";

const client = StreamChat.getInstance("api_key");

export const App = () => (
  <OverlayProvider>
    <Chat client={client}>
      <Channel channel={channel}>
        <MessageList />
        <MessageComposer />
      </Channel>
    </Chat>
  </OverlayProvider>
);

TypeScript

File type

The File type is now exported from the stream-chat-react-native package and extends the FileReference type from the stream-chat package. It looks like this:

import { FileReference } from "stream-chat";

export type File = FileReference;

Props

Most configuration lives on the Channel component. See Customizing Message Composer for UI customization.

PropDescriptionType
attachmentPickerBottomSheetHeightHeight of the attachment picker bottom sheet when open. Defaults to 40% of Window Height.number
attachmentSelectionBarHeightHeight of the attachment selection bar in the attachment picker. Defaults to 52.number
bottomInsetOffsets the MessageList when the attachment picker opens. For most apps, set bottomInset on Channel instead. Use this prop only to override bottomInset from AttachmentPickerContext for a specific composer instance.number | undefined
additionalTextInputPropsExtra props passed to the underlying TextInput in MessageComposer.object
asyncMessagesLockDistancePixels the user must drag upward to lock recording and lift their finger without stopping it. Defaults to 50.number
asyncMessagesMinimumPressDurationMinimum press duration (ms) on the record button to start voice recording. Defaults to 500.number
audioRecordingSendOnCompleteControls what happens after a completed voice recording upload. When true, sends the voice recording immediately after upload. When false, keeps it in the composer so the user can add text, attachments, or more recordings before sending. Defaults to true.boolean
asyncMessagesSlideToCancelDistancePixels the user must drag toward the leading side to cancel voice recording. Defaults to 100.number
audioRecordingEnabledEnable or disable audio recording. Defaults to false.boolean
channelChannel instance from the Stream Chat client.Channel
closeAttachmentPickerDismiss the attachment picker, if its already open.function
closePollCreationDialogFunction called whenever the close button is pressed on the poll creation modal. Has no effect if PollCreateContent is custom.function
compressImageQualityImage compression quality used by the message input upload flow.number
cooldownEndsAtThe time at which the active cool-down will end.Date
editingWhether the message input is in edit mode.-
inputBoxRefRef for TextInput component within MessageComposer.React ref
isOnlineThe value is true when current user is connected to chat.boolean
messageInputFloatingRenders the input in floating mode with adjusted container behavior/styles. Defaults to false.boolean
messageInputHeightStoreStore used internally to track and share the current input height.MessageInputHeightStore
openPollCreationDialogFunction used to open the poll creation dialog.() => void
membersMembers of current channel. This value is received from backend when you query a channel, either using client.queryChannels() or channel.watch() API call. Note: these calls return only up to 100 members; use client.queryMembers() for larger channels.object
selectedPickerValue is 'images' when image attachment picker is open, else undefined.'images' | undefined
sendMessageSends a composed message within MessageComposer component to channel. Attached to the onPress handler of SendButton. The message optimistically gets added to message list UI first, before making API call to server.function
showPollCreationDialogA boolean signifying whether the poll creation dialog is shown or not. Will always be false if PollCreateContent is custom.boolean
createPollOptionGapControls spacing between poll options in the poll creation modal.number
threadListIndicates the Channel is rendering a thread. Used to avoid concurrency issues between the main channel and thread.boolean
watchersWatchers of current channel. This value is received from backend when you query a channel, either using client.queryChannels() or channel.watch() API call. Note: these calls return only up to 100 watchers; use Channel Pagination for more.object

UI Component Overrides

The UI components used by MessageComposer are read from ComponentsContext and can be customized via WithComponents. Wrap MessageComposer (or any ancestor) with WithComponents and pass the components you want to override.

import { WithComponents } from "stream-chat-react-native";

<WithComponents
  overrides={{ SendButton: CustomSendButton, Reply: CustomReply }}
>
  <Channel channel={channel}>
    <MessageList />
    <MessageComposer />
  </Channel>
</WithComponents>;

The following components can be overridden:

PropDescriptionTypeDefault
AttachmentUploadPreviewListRenders previews of attached files and images in MessageComposer.ComponentTypeAttachmentUploadPreviewList
AttachmentPickerSelectionBarRenders the attachment picker selection bar (image, file, camera icons).ComponentTypeundefined | AttachmentPickerSelectionBar
AudioRecorderCustom UI for audio recorder controls in MessageComposer.ComponentTypeAudioRecorder
AudioRecordingInProgressCustom UI for an in-progress audio recording in MessageComposer (waveform, duration, etc.).ComponentTypeAudioRecordingInProgress
AudioRecordingLockIndicatorCustom lock indicator for audio recording in MessageComposer.ComponentTypeAudioRecordingLockIndicator
AudioRecordingPreviewCustom UI to preview and play an audio recording in MessageComposer.ComponentTypeAudioRecordingPreview
AudioRecordingWaveformCustom waveform UI for audio recording in MessageComposer.ComponentTypeAudioRecordingWaveform
AutoCompleteSuggestionListRenders the autocomplete suggestion list.ComponentTypeAutoCompleteSuggestionList
CooldownTimerRenders a countdown timer for message send cooldowns in MessageComposer.ComponentTypeCooldownTimer
MessageComposerLeadingViewCustom component rendered in the leading composer slot.ComponentTypeMessageComposerLeadingView
MessageComposerTrailingViewCustom component rendered in the trailing composer slot.ComponentTypeMessageComposerTrailingView
CreatePollContentA custom UI component used to render the entire poll creation form. It has access to the CreatePollContext values by default through the useCreatePollContext hook.ComponentTypeCreatePollContent
InputRenders the UI for the enclosed MessageComposer. See Customizing Message Composer.ComponentType-
InputButtonsRenders action buttons (AttachButton) on the left side of the MessageComposer.ComponentTypeInputButtons
ReplyRenders a preview of the parent message for quoted replies.ComponentTypeReply
SendButtonRenders the send message button inside MessageComposer.ComponentTypeSendButton
ShowThreadMessageInChannelButtonRenders a checkbox in Thread that sets show_in_channel to true when checked.ComponentTypeShowThreadMessageInChannelButton
StartAudioRecordingButtonCustom mic button for audio recording in MessageComposer.ComponentTypeStartAudioRecordingButton
StopMessageStreamingButtonCustom button to stop AI generation, shown instead of SendButton in MessageComposer.componentStopMessageStreamingButton
MessageInputHeaderViewCustom component rendered above the input body for reply/edit/preview content.ComponentTypeMessageInputHeaderView
MessageInputLeadingViewCustom component rendered in the leading inline input area.ComponentTypeMessageInputLeadingView
MessageInputTrailingViewCustom component rendered in the trailing inline input area.ComponentTypeMessageInputTrailingView
TextInputComponentThe component prop to override the default TextInput component used in the message input's AutoCompleteInput.ComponentTypeDefault React Native's TextInput