# Message UI

The Message UI component consumes [`MessageContext`](/chat/docs/sdk/react/components/contexts/message_context/) and renders a message. The default implementation is [`MessageSimple`](https://github.com/GetStream/stream-chat-react/blob/master/src/components/Message/MessageSimple.tsx).

## Best Practices

- Start by composing the exported message subcomponents instead of rebuilding the whole surface.
- Use `useMessageContext()` inside custom message UI.
- Set shared defaults with `WithComponents` and use list-level overrides only when the customization is local.
- Keep channel and thread message UIs consistent unless the product intentionally treats them differently.
- Preserve the default message layout semantics for accessibility and keyboard behavior.

## Basic Usage

To set a shared default message UI for a `Channel` subtree, register it with `WithComponents`:

```tsx
import {
  Channel,
  ChannelHeader,
  MessageComposer,
  MessageList,
  Thread,
  Window,
  WithComponents,
  useMessageContext,
} from "stream-chat-react";

const CustomMessage = () => {
  const { message } = useMessageContext();

  return <div>{message.text}</div>;
};

const App = () => (
  <WithComponents
    overrides={{
      Message: CustomMessage,
      VirtualMessage: CustomMessage,
    }}
  >
    <Channel>
      <Window>
        <ChannelHeader />
        <MessageList />
        <MessageComposer />
      </Window>
      <Thread />
    </Channel>
  </WithComponents>
);
```

If you only want to customize one list, use the list-level `Message` prop:

```tsx
import { MessageList, Thread, VirtualizedMessageList } from "stream-chat-react";

<MessageList Message={CustomMessage} />;
<Thread Message={CustomMessage} />;
<VirtualizedMessageList Message={CustomMessage} />;
```

## UI Customization

`MessageSimple` is built from smaller UI pieces that each consume `MessageContext`. A custom message UI often looks like a variation of this structure:

```tsx
import {
  Attachment,
  MessageActions,
  MessageReactions,
  MessageRepliesCountButton,
  MessageStatus,
  MessageText,
  MessageTimestamp,
  Poll,
  QuotedMessage,
  useChatContext,
  useMessageContext,
} from "stream-chat-react";

const CustomMessage = () => {
  const { client } = useChatContext();
  const { handleAction, handleOpenThread, message } = useMessageContext();
  const poll = message.poll_id ? client.polls.fromState(message.poll_id) : null;

  return (
    <div className="custom-message">
      <MessageActions />
      {poll && <Poll poll={poll} />}
      {message.quoted_message && <QuotedMessage />}
      {message.attachments?.length ? (
        <Attachment
          actionHandler={handleAction}
          attachments={message.attachments}
        />
      ) : null}
      <MessageText />
      <MessageReactions />
      {!!message.reply_count && (
        <MessageRepliesCountButton
          onClick={handleOpenThread}
          reply_count={message.reply_count}
          thread_participants={message.thread_participants}
        />
      )}
      <MessageTimestamp />
      <MessageStatus />
    </div>
  );
};
```

Other exported building blocks such as `MessageDeletedBubble`, `MessageBlocked`, `MessageTranslationIndicator`, `ReminderNotification`, `MessageAlsoSentInChannelIndicator`, and `StreamedMessageText` can be composed the same way.

## Current Override Paths

- Use `WithComponents overrides={{ Message: CustomMessage }}` to set the default non-virtualized message UI for a subtree.
- Use `WithComponents overrides={{ VirtualMessage: CustomMessage }}` to set the default virtualized message UI for a subtree.
- Use `<MessageList Message={CustomMessage} />`, `<Thread Message={CustomMessage} />`, or `<VirtualizedMessageList Message={CustomMessage} />` for local overrides.
- Use [`MessageActions`](/chat/docs/sdk/react/experimental/message-actions/) to customize the action menu and quick actions.

## Props

| Prop                                  | Description                                                                                                                                                                                                                                                                                   | Type                           |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
| partial `MessageContextValue` surface | Custom message UI components can receive a partial `MessageContextValue` prop surface, but the recommended approach is to call `useMessageContext()` directly. That keeps the component aligned with the current SDK data flow and avoids relying on which values are injected by the caller. | `Partial<MessageContextValue>` |


---

This page was last updated at 2026-04-22T11:55:39.543Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/components/message-components/message_ui/](https://getstream.io/chat/docs/sdk/react/components/message-components/message_ui/).