# Hello Stream Chat

Adding feature rich chat to a React Native application can be quite challenging when starting from scratch.
There are many considerations, states, and edge cases that need accounting for, styling, message grouping, read states, context menus, etc. all add to the complexity of the challenge.
Stream Chat for React Native provides an easy to implement flexible solution.

Stream Chat for React Native provides a way to add chat to an existing or new application with very little code.
The library was built with flexibility and customization in mind, starting with the out of the box form and function one would expect from a chat app you can modify the UI and UX as desired.

Before starting make sure you have installed `stream-chat-react-native` as directed in the [getting started](/chat/docs/sdk/react-native/v3/) guide.

## Creating a Chat Client

Stream Chat for React Native uses [`stream-chat`](https://github.com/GetStream/stream-chat-js), Stream's JavaScript client, to interact with Stream's chat services.
`stream-chat` is a dependency of Stream Chat for React Native so it is can be used once `stream-chat-react-native` is installed.

To start you must get an instance of Stream Chat, for this you will need an API key.
To create one you can sign up for a [free 30-day trial](https://getstream.io/chat/trial/) of Stream Chat, no CC is required.

```ts
import { StreamChat } from "stream-chat";

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

There are multiple ways to access the client throughout your application. You can store the client in a [`context`](https://reactjs.org/docs/context.html).
Create your own class. Or using the Singleton structure you can call `getInstance` when required.

## Connecting a User

Tokens are used to authenticate a user.
Typically, you send this token from your backend to the client when a user registers or logs in.
See the [Tokens & Authentication](/chat/docs/javascript/tokens_and_authentication/) documentation to learn more about creating tokens.
You can use a [developer token](/chat/docs/javascript/tokens_and_authentication/#developer-tokens/) if desired, but for the purpose of this guide it will be assumed you have created and retrieved a `user_token`.

To connect a user the `connectUser` function should be called and provided with the user object and `user_token`.
Connecting a user could be done in the login flow or elsewhere in the application after the client is instantiated.

```ts
await client.connectUser(
  {
    id: "jlahey",
    name: "Jim Lahey",
    image: "https://i.imgur.com/fR9Jz14.png",
  },
  "user_token",
);
```

It is recommended to not repeatedly call `connectUser` unnecessarily, multiple calls to `connectUser` will result in warnings, and attempting to call `connectUser` before disconnecting a current user will throw an Error.

To disconnect a user you can call `disconnectUser` on the client.

```ts
await client.disconnectUser();
```

## Creating a Channel

Channels are at the core of Stream Chat, they are where messages are contained, sent, and interacted with.
Before delving into the UI components a channel is needed that can be displayed.
Let’s start by initializing one.

A [channel type](/chat/docs/javascript/creating_channels#channel-data/) is required for creating a channel and controls the settings for a given channel.
There are 5 default types of channels.

- `commerce`
- `gaming`
- `livestream`
- `messaging`
- `team`

These five options provide you with sensible defaults for the named use cases.
You can also define custom channel types if Stream Chat defaults don’t work for your use case.

A channel must be initialized with either an `id` or a list of members for the channel.
If you provide a list of members an `id` will be auto-generated on backend for the channel.

<admonition type="note">

You can't add or remove members from channel created using a list of members.

</admonition>

You can also add additional custom data to a channel.
You can add as many custom fields as you desire as long as the total size of the custom fields object is _less than 5KB_.

For the purpose of this guide you should create a `channel` as you see fit utilizing either a members list that includes your user's `id`, or a channel `id`.
**This can be done once, then the code removed** as this guide will not be covering on the fly channel creation.

<tabs>

<tabs-item value="channelId" label="Channel Id">

```ts
/**
 *  Channel created using a channel id
 */
const channel = client.channel("messaging", "the_park", {
  name: "The Park",
});
```

</tabs-item>

<tabs-item value="members" label="Members List">

```ts
/**
 *  Channel created using a members list
 */
const channel = client.channel("messaging", {
  members: ["jlahey", "rlafleur"],
  name: "The Park",
});
```

</tabs-item>

</tabs>

To create this channel on the server you must call `create` on the new channel instance.

```ts
await channel.create();
```

<admonition type="note">

For on the fly channel creation you would instead call the `watch` function on the channel as this both creates the channel and subscribes the client to channel updates.

</admonition>

## Configuring UI Components

Now that you have a `client` instance, a user set, and a channel created on the server you can setup your project to use the UI components.

All major `stream-chat-react-native` components rely on `contexts` to function properly.
The UI and functionality are heavily controlled by a number of components that contain [`Providers`](https://reactjs.org/docs/context.html#contextprovider) to give access to these `contexts`.

### Overlay Provider

The `OverlayProvider` is the highest level of the Stream Chat components.
The `OverlayProvider` allows users to interact with messages on long press above the underlying views, use the full screen image viewer, and use the `AttachmentPicker` as a keyboard-esk view.

The `OverlayProvider` can be used with no props provided but there are a plethora of props for customizing the components in the overlay.

For additional information on the `OverlayProvider` check the [OverlayProvider docs](/chat/docs/sdk/react-native/v3/core-components/overlay-provider/) for detailed usage instructions, including how to properly use the `OverlyProvider` with [React Navigation](https://reactnavigation.org/).

```tsx
import { OverlayProvider } from "stream-chat-react-native";

export const Screen = () => (
  <OverlayProvider>{/** App components */}</OverlayProvider>
);
```

### Chat

`Chat` is the next level down of context component from `OverlyProvider` that is required for `stream-chat-react-native` to function as designed.
You can choose to wrap your entire application in `Chat` similar to what is required for the `OverlayProvider` or you can implement `Chat` at the screen level.
`Chat` has one required prop, `client`, which is the instance of `StreamChat` [you created](#creating-a-chat-client).

For additional information on the `Chat` component check the [Chat component docs](/chat/docs/sdk/react-native/v3/core-components/chat/) for detailed usage instructions, including how to provide theming and translations to the app.

<tabs>

<tabs-item value="app" label="App">

```tsx {8-10}
import { StreamChat } from "stream-chat";
import { Chat, OverlayProvider } from "stream-chat-react-native";

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

export const App = () => (
  <OverlayProvider>
    <Chat client={client}>{/** App components */}</Chat>
  </OverlayProvider>
);
```

</tabs-item>

<tabs-item value="screen" label="Screen">

```tsx
import { StreamChat } from "stream-chat";
import { Chat } from "stream-chat-react-native";

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

export const Screen = () => (
  <Chat client={client}>{/** App components */}</Chat>
);
```

```tsx {6}
import { OverlayProvider } from "stream-chat-react-native";
import { Screen } from "./Screen";

export const App = () => (
  <OverlayProvider>
    <Screen />
  </OverlayProvider>
);
```

</tabs-item>

</tabs>

## Channel List

Stream Chat for React Native provides a `ChannelList` component out of the box for displaying a list of channels.
`ChannelList` can be used with no props and will return all of the channels the set user has access to.
To functionally use the `ChannelList` an `onSelect` prop should be provided.
The `onSelect` function is called with the selected `Channel` instance and can then be used to react to the user interaction, for example store the `Channel` in state and navigate to the appropriate channel screen.

For additional information on the `ChannelList` component check the [ChannelList component docs](/chat/docs/sdk/react-native/v3/core-components/channel-list/), these include instructions on how to filter and sort the `ChannelList`.

The `ChannelList` should be implemented inside of the UI components [previously configured](#configuring-ui-components) to provide the appropriate `contexts`.
For the purpose of this guide the example implementation will continue to be given in a single component with the assumption that the client has already been instantiated, a user connected, and a channel the user has access to exists.

![ChannelList](/data/docs/chat-sdk/react-native/v3/_assets/basics/hello-stream-chat/channel_list.png)

```tsx {9}
import { StreamChat } from "stream-chat";
import { ChannelList, Chat, OverlayProvider } from "stream-chat-react-native";

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

export const App = () => (
  <OverlayProvider>
    <Chat client={client}>
      <ChannelList />
    </Chat>
  </OverlayProvider>
);
```

These three components in conjunction will provide a [`FlatList`](https://reactnative.dev/docs/flatlist) of all channels available to the connected user.

## Channel

When creating a chat screen it is required that the `Channel` component wrap the `stream-chat-react-native` components being used.
`Channel` provides multiple `contexts` to the enclosed components and allows for modification and replacement of many of the components.
Channel is the major entry point for modifying the look and feel of your chat application.

For additional information on the `Channel` component, how to modify various features, adjusting for keyboard offsets, and more, check the [Channel component docs.](/chat/docs/sdk/react-native/v3/core-components/channel/)

The `Channel` component does not require any props, but will not function as desired without the `channel` prop being provided.
The `channel` prop expects a `StreamChat` `Channel` instance.
This can be created [as you did previously](#creating-a-channel), pulled directly from the `client.activeChannels`, or conveniently stored when a channel is selected from the `ChannelList`.

```tsx {8,13-19}
import React, { useState } from "react";
import { Channel as ChannelType, StreamChat } from "stream-chat";
import { ChannelList, Chat, OverlayProvider } from "stream-chat-react-native";

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

export const App = () => {
  const [channel, setChannel] = useState<ChannelType>();

  return (
    <OverlayProvider>
      <Chat client={client}>
        {channel ? (
          <Channel channel={channel}>{/** App components */}</Channel>
        ) : (
          <ChannelList onSelect={setChannel} />
        )}
      </Chat>
    </OverlayProvider>
  );
};
```

### Message List

The `Channel` component on it's own will not provide any UI.
For this additional components are required, most notably the `MessageList` component.
`MessageList` has no required props, and when used in concert with the `Channel` component should function properly out of the box.

For additional information on the `MessageList` component, how to pass props to the underlying [`FlatList`](https://reactnative.dev/docs/flatlist), or use the `MessageList` for threads, check the [MessageList component docs.](/chat/docs/sdk/react-native/v3/ui-components/message-list/)

![MessageList](/data/docs/chat-sdk/react-native/v3/_assets/basics/hello-stream-chat/message_list.png)

```tsx {15}
import React, { useState } from "react";
import { Channel as ChannelType, StreamChat } from "stream-chat";
import { ChannelList, Chat, OverlayProvider } from "stream-chat-react-native";

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

export const App = () => {
  const [channel, setChannel] = useState<ChannelType>();

  return (
    <OverlayProvider>
      <Chat client={client}>
        {channel ? (
          <Channel channel={channel}>
            <MessageList />
          </Channel>
        ) : (
          <ChannelList onSelect={setChannel} />
        )}
      </Chat>
    </OverlayProvider>
  );
};
```

### Message Input

A chat app needs to be able to send messages, and for this Stream Chat for React Native provides a `MessageInput` component.
Similar to the `MessageList` component `MessageInput` has no required props.
Adding it to the app is as simple as rendering it below the `MessageList`.

Be sure to set the `keyboardVerticalOffset` on `Channel` to the appropriate height based off any header spacing.
As there is currently no header the `keyboardVerticalOffset` can be set to `0`.

For additional information on the `MessageInput` component, how to modify it using `context`, or designate it for thread use via the `threadList` prop, check the [MessageInput component docs.](/chat/docs/sdk/react-native/v3/ui-components/message-input/)

![MessageInput](/data/docs/chat-sdk/react-native/v3/_assets/basics/hello-stream-chat/message_input.png)

```tsx {14,16}
import React, { useState } from "react";
import { Channel as ChannelType, StreamChat } from "stream-chat";
import { ChannelList, Chat, OverlayProvider } from "stream-chat-react-native";

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

export const App = () => {
  const [channel, setChannel] = useState<ChannelType>();

  return (
    <OverlayProvider>
      <Chat client={client}>
        {channel ? (
          <Channel channel={channel} keyboardVerticalOffset={0}>
            <MessageList />
            <MessageInput />
          </Channel>
        ) : (
          <ChannelList onSelect={setChannel} />
        )}
      </Chat>
    </OverlayProvider>
  );
};
```

This small code snippet is enough to render a list of channels and swap them out for a functional and feature rich message list and input when one is selected.

### Thread

There is one more high level component that Stream Chat for React Native provides out of the box, and that is `Thread`.
Stream Chat supports threaded messages, and the `MessageList` supplies a UI for threads out of the box.
But as a thread on a mobile messaging app generally exists in a separate screen it is up to you to handle thread selection and subsequent navigation in your implementation.
`Thread` has no required props as it relies heavily on `context` to function.
The simple code snippet can be extended to include `Thread` and keep track of a `thread` state similarly to `channel` by utilizing the `onThreadSelect` prop on the `MessageList`.
The code snippet now has a fully functional `ChannelList`, `MessageList`, and `threadList`, although currently it provides no way to _back_ out of the sudo-navigation.

For additional information on the `Thread` component, such as how to use `onThreadDismount` to manage your `thread` state, check the [Thread component docs.](/chat/docs/sdk/react-native/v3/ui-components/thread/)

![Thread](/data/docs/chat-sdk/react-native/v3/_assets/basics/hello-stream-chat/thread.png)

```tsx {9,15-24}
import React, { useState } from "react";
import { Channel as ChannelType, StreamChat } from "stream-chat";
import {
  ChannelList,
  Chat,
  MessageType,
  OverlayProvider,
} from "stream-chat-react-native";

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

export const App = () => {
  const [channel, setChannel] = useState<ChannelType>();
  const [thread, setThread] = useState<MessageType | null>();

  return (
    <OverlayProvider>
      <Chat client={client}>
        {channel ? (
          <Channel channel={channel} keyboardVerticalOffset={0} thread={thread}>
            {thread ? (
              <Thread />
            ) : (
              <>
                <MessageList onThreadSelect={setThread} />
                <MessageInput />
              </>
            )}
          </Channel>
        ) : (
          <ChannelList onSelect={setChannel} />
        )}
      </Chat>
    </OverlayProvider>
  );
};
```

## Summary

- You need a `client` that is an instance of `StreamChat` to provide to the UI components so they function correctly.

- You need to connect a user via the `connectUser` call to interact with the backend properly.
  To do this you need to create tokens as per the [Tokens & Authentication](/chat/docs/javascript/tokens_and_authentication/) docs.

- You need to surround your app with the `OverlayProvider` for the UI to function properly, and your app or chat screen with the `Chat` component to provide data to the UI components.

- `ChannelList` provides access to the list of available channels in the UI, and using props, can be queried, filtered, and sorted as desired.
  `ChannelList` also provides convenient functionality for implementing navigation to a selected `Channel`.

- The `Channel` component is the functional wrapper of the `MessageList`, `MessageInput`, and `Thread` components.
  It is the access point for the majority of the customization of the SDK, and controls much of the functionality.

### Hello Stream Chat

Putting everything covered together into a single functional component most of the Stream Chat for React Native SDK can be tested with a few additional setup.

The final sample code:

- Adds a `useEffect` to connect the user on mount and render the UI when ready.
- Adds a `back` button for sudo-navigation by resetting the states of `thread` and `channel` when appropriate.
- Adds a `View` around the `Chat` component with style `flex: 1` to allow `Chat` to adjust for the `back` button height, and an empty `Thread` component to layout properly.
- Adjusts the `topInset` and `keyboardVerticalOffset` to account for the `back` button height.

These additions result in a small but functional chat sample app.

![Summary](/data/docs/chat-sdk/react-native/v3/_assets/basics/hello-stream-chat/summary.png)

```tsx
import React, { useEffect, useState } from "react";
import { View, TouchableOpacity, Text } from "react-native";
import { Channel as ChannelType, StreamChat } from "stream-chat";
import {
  Channel,
  ChannelList,
  Chat,
  MessageInput,
  MessageList,
  MessageType,
  OverlayProvider,
  Thread,
} from "stream-chat-react-native";

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

export const App = () => {
  const [channel, setChannel] = useState<ChannelType>();
  const [clientReady, setClientReady] = useState(false);
  const [thread, setThread] = useState<MessageType | null>();

  useEffect(() => {
    const setupClient = async () => {
      try {
        await client.connectUser(
          {
            id: "jlahey",
            name: "Jim Lahey",
            image: "https://i.imgur.com/fR9Jz14.png",
          },
          "user_token",
        );
        setClientReady(true);
      } catch (e) {
        console.log(e);
      }
    };

    setupClient();
  }, []);

  const onBackPress = () => {
    if (thread) {
      setThread(undefined);
    } else if (channel) {
      setChannel(undefined);
    }
  };

  if (!clientReady) return null;

  return (
    <OverlayProvider topInset={60}>
      <TouchableOpacity onPress={onBackPress} disabled={!channel}>
        <View style={{ height: 60, paddingLeft: 16, paddingTop: 40 }}>
          {channel && <Text>Back</Text>}
        </View>
      </TouchableOpacity>
      <View style={{ flex: 1 }}>
        <Chat client={client}>
          {channel ? (
            <Channel
              channel={channel}
              keyboardVerticalOffset={60}
              thread={thread}
            >
              {thread ? (
                <Thread />
              ) : (
                <>
                  <MessageList onThreadSelect={setThread} />
                  <MessageInput />
                </>
              )}
            </Channel>
          ) : (
            <ChannelList onSelect={setChannel} />
          )}
        </Chat>
      </View>
    </OverlayProvider>
  );
};
```


---

This page was last updated at 2026-03-13T13:14:08.280Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v3/basics/hello_stream_chat/](https://getstream.io/chat/docs/sdk/react-native/v3/basics/hello_stream_chat/).