Getting Started

This section gives a high-level overview of setup, core components, and how they fit together. For a full step-by-step React app setup, see the React Chat tutorial.

Best Practices

  • Follow the tutorial once end-to-end before diverging into custom layouts.
  • Keep Chat and Channel as the top-level providers to ensure contexts flow correctly.
  • Use useCreateChatClient for lifecycle management; avoid manual connect/disconnect logic.
  • Start with default components and override selectively to minimize custom surface area.
  • Define channel types and permissions early so UI behavior matches server rules.

Your First App with Stream Chat React

Before starting, install stream-chat-react (and stream-chat) as described in Installation.

You’ll also need to create a Stream Chat app and generate a user token.

The example below is the minimum code to render a working chat UI.

The Chat and Channel components are React context providers. They pass UI, state, and action handlers to their children.

import {
  Chat,
  Channel,
  ChannelList,
  Window,
  ChannelHeader,
  MessageList,
  MessageInput,
  Thread,
  useCreateChatClient,
} from "stream-chat-react";
import "stream-chat-react/dist/css/v2/index.css";

const apiKey = "your-api-key";
const userId = "user-id";
const token = "authentication-token";

const filters = { members: { $in: [userId] }, type: "messaging" };
const options = { presence: true, state: true };
const sort = { last_message_at: -1 };

const App = () => {
  const client = useCreateChatClient({
    apiKey,
    tokenOrProvider: token,
    userData: { id: userId },
  });

  if (!client) return <div>Loading...</div>;

  return (
    <Chat client={client}>
      <ChannelList sort={sort} filters={filters} options={options} />
      <Channel>
        <Window>
          <ChannelHeader />
          <MessageList />
          <MessageInput />
        </Window>
        <Thread />
      </Channel>
    </Chat>
  );
};

To organize the components in a chat messenger layout, you can start with the following SCSS:

html,
body,
#root {
  margin: unset;
  padding: unset;
  height: 100%;
}

#root {
  display: flex;
  height: 100%;

  .str-chat__channel-list {
    position: fixed;
    z-index: 1;
    height: 100%;
    width: 0;
    flex-shrink: 0;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.15);

    &--open {
      width: 30%;
      position: fixed;
    }
    transition: width 0.3s ease-out;
  }

  .str-chat__channel {
    flex: 1;
    min-width: 0;
  }

  .str-chat__main-panel {
    min-width: 0;
    flex: 1;

    &--thread-open {
      display: none;
    }
  }

  .str-chat__thread {
    flex: 1;
    height: 100%;
    position: fixed;
    z-index: 1;
  }

  .str-chat__channel-header .str-chat__header-hamburger {
    width: 30px;
    height: 38px;
    padding: var(--xxs-p);
    margin-right: var(--xs-m);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border: none;
    background: transparent;

    &:hover {
      svg path {
        fill: var(--primary-color);
      }
    }
  }

  @media screen and (min-width: 768px) {
    .str-chat__channel-list {
      width: 30%;
      position: initial;
      z-index: 0;
    }

    .str-chat__thread {
      position: initial;
      z-index: 0;
    }

    .str-chat__channel-header .str-chat__header-hamburger {
      display: none;
    }
  }

  @media screen and (min-width: 1024px) {
    .str-chat__main-panel {
      min-width: 0;

      &--thread-open {
        max-width: 55%;
        display: flex;
      }
    }

    .str-chat__thread {
      max-width: 45%;
    }

    .str-chat__channel-header .str-chat__header-hamburger {
      display: none;
    }
  }
}

Chat Client & Connecting User

To communicate with the Stream Chat API the SDK requires a client with an established connection.

The useCreateChatClient hook instantiates the client, connects the user, and cleans up on unmount.

The useCreateChatClient hook accepts an options object forwarded to the StreamChat constructor. The client is not recreated when options changes. If you need to re-create it, set a key on the component that calls the hook:

import { Chat, StreamChatOptions, useCreateChatClient } from 'stream-chat-react';

const App = () => {
  const [timeout, setTimeout] = useState(6000);
  const key = `timeout_${timeout}`;
  return <ChatWithOptions key={key} timeout={timeout} />;
};

const ChatWithOptions = ({ timeout }: StreamChatOptions) => {
  const client = useCreateChatClient({
    apiKey,
    options: { timeout },
    tokenOrProvider: token,
    userData: { id: userId },
  });

  if (!client) return <div>Loading...</div>;
  return <Chat client={client}></Chat>;
};

Creating a Channel

Channels are the core of Stream Chat. Once you initialize a channel object, the `Channel` component consumes it and renders the channel UI.

By default, the Stream Chat API provides support for five different channel types of varying use cases. A channel type is required when creating a channel and dictates the available features and permissions.

The defaults include:

  • messaging
  • livestream
  • team
  • gaming
  • commerce

You can also create custom channel types and define your own permission sets.

To create a channel, call client.channel with:

  • channel type
  • channel ID (optional; auto-generated if omitted)
  • channel data
const channel = client.channel("messaging", {
  image: "https://cdn.com/image.png",
  name: "Just Chatting",
  members: ["dave-matthews", "trey-anastasio"],
  // option to add custom fields
});

Setting Up the Components

With a client, connected user, and channel, you can compose the core UI components.

Chat

The Chat component wraps your app and provides the ChatContext (including the StreamChat client). All other SDK components must be children of Chat.

The client instance can be accessed with our custom context hook:

import { useChatContext } from "stream-chat-react";

// ...

const { client } = useChatContext();

Channel

The Channel component wraps the logic, state, and UI for a channel. It provides four contexts:

ChannelList

The ChannelList renders a channel list and previews. If you use ChannelList, don’t pass a channel prop to ChannelChannelList handles that internally.

Window

The Window component manages layout changes when opening or closing a Thread.

ChannelHeader

The ChannelHeader displays the active channel’s image and title.

MessageList

The MessageList renders messages and consumes the contexts provided by Channel. It accepts many optional props for customization.

MessageInput

The MessageInput component wraps the message composer UI and provides the MessageInputContext.

Thread

The Thread component renders replies for a parent message. It maintains its own state and renders a MessageList and MessageInput.

Emojis (picker & autocomplete)

The SDK supports emoji picker and autocomplete integrations. Emoji autocomplete is built on emoji-mart.

The SDK does not ship with a built-in emoji picker or emoji search index. You'll need to install and configure these yourself. See the Emoji Picker guide for setup instructions.

Read more about customization in our Theming and UI Cookbook guides.