# How to Implement a Chat Component for Messaging UIs in Astryx

> Learn how to implement a chat component for messaging UIs in Astryx using the @astryxdesign/lab package. Build production-ready chat interfaces with message bubbles, typing indicators, and emoji reactions.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-07-14

---

**Astryx provides a complete set of ready-made building blocks under the `@astryxdesign/lab` package that enables you to assemble production-ready chat interfaces with support for message bubbles, unread separators, typing indicators, and emoji reactions.**

The `facebook/astryx` repository offers a robust design system for building modern messaging interfaces. By leveraging the specialized components in the `@astryxdesign/lab` package, you can implement a fully functional Chat component for messaging UIs in Astryx that handles complex interactions like mentions, reactions, and real-time typing status.

## Core Architecture of the Chat System

The Astryx chat implementation follows a clear separation of concerns across three distinct layers, each handling specific responsibilities within the messaging interface.

### Message List and Layout Layer

The foundation rests on `ChatLayout` and `ChatMessageList` components. As implemented in [`ChatLayoutShowcase.tsx`](https://github.com/facebook/astryx/blob/main/ChatLayoutShowcase.tsx) and [`ChatMessageListShowcase.tsx`](https://github.com/facebook/astryx/blob/main/ChatMessageListShowcase.tsx), these containers manage the scrollable message area, header placement, and overall scaffold. The layout component provides the structural wrapper while the message list handles virtualization and scroll positioning for large conversation histories.

### Message Bubble and Metadata Layer

Individual messages render through `ChatMessageBubble`, with dedicated variants handling different densities and grouping styles. The [`ChatMessageBubbleGrouping.tsx`](https://github.com/facebook/astryx/blob/main/ChatMessageBubbleGrouping.tsx) showcase demonstrates how consecutive messages from the same sender collapse visually to reduce clutter. Each bubble supports metadata display including avatars, timestamps, and delivery status indicators.

### Interaction and Input Layer

User interactions are handled by specialized components: `ChatReactionBar` for emoji responses, `ChatTypingIndicator` for real-time status, and `ChatComposerInput` for message entry with support for mentions and dictation. These components coordinate to create a responsive messaging experience without managing complex state manually.

## Step-by-Step Implementation Guide

### Import the Component Library

Begin by importing the necessary components from the `@astryxdesign/lab` package. The library exports all chat primitives required for a complete implementation.

```tsx
import {
  ChatLayout,
  ChatMessageList,
  ChatMessageBubble,
  ChatUnreadDivider,
  ChatTypingIndicator,
  ChatReactionBar,
  ChatComposerInput,
} from '@astryxdesign/lab';

```

### Create the Layout Container

Wrap your chat interface with `ChatLayout` to establish the header, message area, and composer structure. This component provides consistent spacing and responsive behavior across screen sizes.

```tsx
<ChatLayout>
  <ChatMessageList>
    {/* Messages will render here */}
  </ChatMessageList>
  
  <ChatComposerInput placeholder="Type a message…" />
</ChatLayout>

```

### Render Messages with Bubbles

Map your message data to `ChatMessageBubble` components, utilizing `ChatMessageBubbleGrouping` for visual continuity between consecutive messages from the same sender. Pass required props including `sender`, `timestamp`, and `status` to control the bubble appearance.

```tsx
<ChatMessageBubble sender="assistant" timestamp="10:32 AM">
  Hello! How can I help you today?
</ChatMessageBubble>

```

### Add Unread Message Separators

Insert `ChatUnreadDivider` at the position where the first unread message appears in the conversation history. According to the source code in [`ChatUnreadDivider.tsx`](https://github.com/facebook/astryx/blob/main/ChatUnreadDivider.tsx), this component renders an error-colored separator with a customizable `label` prop that defaults to "New".

```tsx
<ChatUnreadDivider label="Unread Messages" />

```

### Display Typing Indicators

When your backend reports active typers, render `ChatTypingIndicator` with an array of participant names. As implemented in [`ChatTypingIndicator.tsx`](https://github.com/facebook/astryx/blob/main/ChatTypingIndicator.tsx), this component handles both single and multiple participants with appropriate grammar adjustments.

```tsx
<ChatTypingIndicator names={['Ana', 'Ben']} />

```

### Enable Emoji Reactions

Attach `ChatReactionBar` to each message bubble to allow users to add reactions. This component, defined in [`ChatReactionBar.tsx`](https://github.com/facebook/astryx/blob/main/ChatReactionBar.tsx), displays existing reaction counts and triggers `ChatEmojiPicker` when users click the add-reaction button.

```tsx
<ChatReactionBar
  reactions={[{emoji: '👍', count: 2}, {emoji: '❤️', count: 1}]}
  onAdd={(emoji) => addReaction(messageId, emoji)}
/>

```

### Configure the Message Composer

Implement `ChatComposerInput` with optional triggers for mentions and dictation. The [`ChatComposerInputMultipleTriggers.tsx`](https://github.com/facebook/astryx/blob/main/ChatComposerInputMultipleTriggers.tsx) showcase provides a reference for handling complex input scenarios including the `ChatComposerInputMentionTrigger` component for `@user` style mentions.

```tsx
<ChatComposerInputMultipleTriggers
  onSubmit={handleSend}
  mentionTrigger={<ChatComposerInputMentionTrigger />}
/>

```

## Complete Working Example

Here is a fully functional implementation combining all layers:

```tsx
import React from 'react';
import {
  ChatLayout,
  ChatMessageList,
  ChatMessageBubble,
  ChatUnreadDivider,
  ChatTypingIndicator,
  ChatReactionBar,
  ChatComposerInput,
} from '@astryxdesign/lab';

export default function ChatDemo() {
  const [messages, setMessages] = React.useState([
    {id: 1, sender: 'assistant', text: 'Welcome!', unread: false},
    {id: 2, sender: 'user', text: 'Hi there', unread: true},
  ]);
  const typing = ['Ana'];

  return (
    <ChatLayout>
      <ChatMessageList>
        {messages.map((msg) => (
          <React.Fragment key={msg.id}>
            {msg.unread && <ChatUnreadDivider label="Unread" />}
            <ChatMessageBubble sender={msg.sender} timestamp="Now">
              {msg.text}
            </ChatMessageBubble>
            <ChatReactionBar
              reactions={[]}
              onAdd={(emoji) => console.log('add', emoji, msg.id)}
            />
          </React.Fragment>
        ))}

        {typing.length > 0 && <ChatTypingIndicator names={typing} />}
      </ChatMessageList>

      <ChatComposerInput placeholder="Type a message…" />
    </ChatLayout>
  );
}

```

## Customization and Theming

All components are built with **StyleX**, respecting design tokens such as `colorVars` and `spacingVars`. To customize the appearance, extend the component's `xstyle` prop with additional StyleX rules or supply a custom theme token set via `themeProps`. This approach ensures type-safe styling while maintaining consistency with the broader Astryx design system.

## Key Source Files and References

Understanding the underlying implementation helps when debugging or extending functionality:

- **[`ChatUnreadDivider.tsx`](https://github.com/facebook/astryx/blob/main/ChatUnreadDivider.tsx)** – Renders the error-colored separator with customizable labels.
- **[`ChatTypingIndicator.tsx`](https://github.com/facebook/astryx/blob/main/ChatTypingIndicator.tsx)** – Handles the display logic for single and multiple typing participants.
- **[`ChatReactionBar.tsx`](https://github.com/facebook/astryx/blob/main/ChatReactionBar.tsx)** – Manages reaction display and triggers the emoji picker.
- **[`ChatEmojiPicker.tsx`](https://github.com/facebook/astryx/blob/main/ChatEmojiPicker.tsx)** – Provides the pop-over interface for selecting reaction emojis.
- **[`ChatMessageListShowcase.tsx`](https://github.com/facebook/astryx/blob/main/ChatMessageListShowcase.tsx)** – Demonstrates full-featured message list implementations including density variants.
- **[`ChatLayoutShowcase.tsx`](https://github.com/facebook/astryx/blob/main/ChatLayoutShowcase.tsx)** – Shows layout configurations with side panels and responsive behavior.
- **[`ChatComposerInputMultipleTriggers.tsx`](https://github.com/facebook/astryx/blob/main/ChatComposerInputMultipleTriggers.tsx)** – Reference implementation for complex composer inputs with mentions and dictation.

## Summary

- **Astryx** provides comprehensive chat primitives in the `@astryxdesign/lab` package, eliminating the need to build messaging UI from scratch.
- The architecture separates concerns into **Layout**, **Message**, and **Interaction** layers for maintainable code organization.
- **Key components** include `ChatLayout`, `ChatMessageList`, `ChatMessageBubble`, `ChatUnreadDivider`, `ChatTypingIndicator`, `ChatReactionBar`, and `ChatComposerInput`.
- All components leverage **StyleX** for performance and theming, with extensive showcase files available in the `facebook/astryx` repository for reference implementations.

## Frequently Asked Questions

### What package contains the Chat components in Astryx?

The chat components are exported from `@astryxdesign/lab`, which is the experimental design system package within the `facebook/astryx` repository. This package contains all messaging primitives including message lists, bubbles, and composer inputs.

### How do I handle mentions in the chat composer?

Use the `ChatComposerInputMultipleTriggers` component with `ChatComposerInputMentionTrigger` as demonstrated in [`ChatComposerInputMultipleTriggers.tsx`](https://github.com/facebook/astryx/blob/main/ChatComposerInputMultipleTriggers.tsx). The trigger system detects `@` symbols and provides autocomplete functionality for selecting users.

### Can I customize the unread divider label?

Yes. The `ChatUnreadDivider` component accepts a `label` prop that allows you to override the default "New" text. Pass any string to customize the separator text for different languages or contexts.

### Does Astryx support grouping consecutive messages?

Yes. The `ChatMessageBubbleGrouping` utility component, showcased in [`ChatMessageBubbleGrouping.tsx`](https://github.com/facebook/astryx/blob/main/ChatMessageBubbleGrouping.tsx), handles visual grouping of consecutive messages from the same sender. This reduces avatar repetition and creates a cleaner conversation flow.