Set Up Your React Environment

The easiest way to build a Stream Chat React JS application from this tutorial is to create a new project using Vite. Vite allows you create a boilerplate React application that you can run locally with just a few simple commands.

Before you start: Make sure you've installed Homebrew (if you're on MacOS) and the most recent versions of Node.js (visit NodeSource and follow installation tutorial for your Linux distribution) and Yarn.

To install Homebrew, run the following command in your terminal:

To install Node with brew for MacOS run:

To install Yarn run:

Next, create a new React project called chat-example with Vite by using the TypeScript template:

Create a WhatsApp or Facebook Messenger Style Chat App

Stream's React Chat messaging SDK component library includes everything you need to build a fully functioning chat experience, with support for rich messages, reactions, threads, image uploads, videos, and more. This library was designed to enable you to get an application up and running quickly and efficiently while supporting customization for complex use cases.

We’ve included a few Stream React Chat examples to show you what’s possible:

  • Basic Chat Components Example
  • ChannelList Example
  • Customizable UI Components Example
  • Custom Attachment Component Example

Build a Basic Chat App with Stream’s Core React Components

In the sample below, you’ll find the following basic chat components in the React JS library:

  • Chat
  • Channel
  • ChannelHeader
  • MessageInput (w/ EmojiPicker & emoji autocomplete)
  • MessageList
  • Thread
  • Window

To get started:

  1. Replace the code in src/App.tsx with the snippet below.
  2. In your terminal, run yarn dev to launch the chat application.

You might've noticed that the application does not look very appealing out of the box - that is because we leave layouting for developers to position their components the way they desire.

But for now, let's create a CSS file (src/layout.css) with a basic layout:

And then we'll import it into src/App.tsx right below stream-chat-react CSS import:

Note: Be sure to get rid of the default src/index.css imports to make sure your styling isn't getting messed up with unwanted rules.

The Chat and Channel components are React context providers that pass a variety of values to their children, including UI components, channel state data, and messaging functions.

Note how you create a channel with the channel method available on the StreamChat client instance. The first argument is the channel type messaging; the second argument is optional and specifies either the channel ID or custom ID.

The channel type determines the enabled features and permissions associated with this channel. The channel ID is a unique reference to this specific channel.

Once you have the app running, you’ll notice the following out-of-the-box features:

  • User online presence
  • Typing indicators
  • Message status indicators (sending, received)
  • User role configuration
  • Emoji support (opt-in)
  • Message read indicators
  • Threading and message replies
  • Message reactions
  • URL previews (send a YouTube link to see this in action)
  • File uploads and previews
  • Video playback
  • Autocomplete-enabled search on users, emojis (opt-in), and commands
  • Slash commands such as /giphy (custom commands are also supported)
  • AI-powered spam and profanity moderation

Create a stable client instance

Before we continue, let's add a React hook that makes sure there are no "race conditions" in React StrictMode in your connect/disconnect implementation and provides stable client instance for your application. Create a new file src/hooks/useClient.ts with the following code:

And now we can use the useClient hook inside the App component to access the client instance;

Note: Make sure you use useClient hook only once per application. If you need the client instance somewhere down in the component tree use useChatContext (exported by the stream-chat-react) hook to access it.

Add a Channel List

ChannelList component displays a list of channel previews. It internally loads the data about the channels relevant to our user. The channels are loaded according to the criteria specified through its props. These props are:

  • filter: Applies a filter to the channels we want to load. We should at least specify we want to load channels of a given type we are members of.
  • sort: Applies a sorting criteria to the channels selected by the filter. We want to sort the channels by the time of the last message.
  • options: Applies some additional options to the query. We want to limit the number of channels we load to 10.

Note: You can read more in the ChannelList documentation.

The next example will show you how to render a list of channels using the ChannelList component. In this example, you’ll:

  1. Filter your channel query by the messaging type and only return channels where the connected user is a member.
  2. Refactor the websocket connection logic to better handle potential race conditions and prevent your app from attempting to load an unconnected client instance (the connectUser method on the StreamChat client instance is asynchronous).
  3. Add the LoadingIndicator component, which will render a loading spinner until the StreamChat client instance sets.

Note: The ChannelList component automatically sets the channel property of the Channel component.

Customizing Your Own UI Components

While all of the React JS components in the library render with default styling, you can also pass via props your own custom UI components to adjust the look and feel of your app to meet your design specifications.

In the below example, you’ll create custom ChannelPreview and Message components.

Note: All custom UI components that override the defaults receive the same props as their default counterparts.

Update src/App.tsx with the following code:

Create a Custom Message Attachment Type

In this example, you’ll create a custom Attachment component that renders a different UI if the attachment is of type product.

To see this functionality in action, you’ll:

  1. Set up your app to automatically send a message with a custom attachment on mount.
  2. Make a query to fetch the created channel after the user connects.
  3. Send a message with the product attachment included. The custom Attachment component will then render in the MessageList.

Update src/App.tsx with the following code:

For more information:

Enable EmojiPicker and emoji autocomplete

No chat experience is complete without emojis - we've made it easy for you to extend your MessageInput component with EmojiPicker component and emoji autocomplete (through the use of SearchIndex).

For this part we'll need emoji-mart related packages on top of which our SDK components are built (make sure versions of these packages fit within our peer dependency requirements), to install these run:

And now the actual code:

Create a Livestream Style Chat App

For the next example, you’ll customize the original code snippet to work well for a livestream style chat application. In livestream apps, the user interface tends to be more compact and message seen/read states can get noisy as volume increases.

For this reason, we've changed the channel type. You'll use the VirtualizedMessageList component, which handles list virtualization out-of-the-box and manages memory build-up.

Update src/App.tsx with the following code to see a simple livestream example:

There are a few important differences compared to the first example:

  • You're using the livestream channel type, which disables typing events and seen/read states.
  • You set the theme to str-chat__theme-dark, which enables dark mode for the livestream channel type.
  • You're using the VirtualizedMessageList component, which supports the high message volume unique to livestream events.

As a next step, check out the GetStream React examples source code for the chat demos on Stream’s website. Here, you can view more detailed integrations and complex use-cases involving Stream's React components.

Final Thoughts

In this chat app tutorial we built a fully functioning React messaging app with our React SDK component library. We also showed how easy it is to customize the behavior and the style of the React chat app components with minimal code changes.

Both the chat SDK for React and the API have plenty more features available to support more advanced use-cases such as push notifications, content moderation, rich messages and more. Please check out our React Native tutorial too. If you want some inspiration for your app, download our free chat interface UI kit.

Give us Feedback!

Did you find this tutorial helpful in getting you up and running with React for adding chat to your project? Either good or bad, we’re looking for your honest feedback so we can improve.

Kiddom logo

We’ve been going at lightspeed to build more communication functionality into Kiddom. The only way to achieve this in four months was to do a chat integration with Stream because we needed to do it reliably and at scale.

Head of Product, Kiddom profile picture

Nick Chen

Head of Product, Kiddom

Next Steps

Create your free Stream account to try out all our Chat product has to offer. No commitment or credit card required. If you want a custom plan or have questions, we are eager to talk with you.

Activity Feeds

Build any kind of feed without the headache of scalability or reliability of your feeds.

Learn more about $ Activity Feeds


Available 99.999% uptime SLAs and industry-leading security to power the world's largest apps.

Learn more about $ Enterprise