React Native Introduction

This section will help you to build any type of chat or messaging experience for a react-native application.

Start here

This SDK is the client half of your integration. App settings, permissions, webhooks, push templates and data retention are configured from your backend with a server-side SDK or the REST API, and the token your app connects with has to be signed there too. See the server-side overview for what belongs there.

How the SDK is structured

Your integration is built from two npm packages:

  • Chat API client (source, npm): a plain JavaScript client for the chat API. It handles connecting to chat, sending messages and creating channels.

  • React Native Component SDK (React Native package, Expo package): ready-made UI components, shipped as separate packages for React Native and Expo. Both rely on the JS client under the hood.

flowchart LR
  app[Your app] --> ui[UI components]
  app -. custom UI .-> client
  ui --> client[stream-chat client]
  client <--> api[Stream API]

Use the component SDK that matches your stack. It handles the stateful chat logic for you, and the components are customisable enough to match your existing app. If you want to build all of your chat UI yourself, use the Chat API client on its own.

You can also take apart the sample apps on GitHub.

Build with Stream CLI and Agent Skills

The Stream CLI and Agent Skills provide AI coding agents, such as Claude Code, Cursor, and Codex, with the tools and knowledge necessary to build apps with Stream.

Install the CLI and add the skills to your project:

curl -fsSL https://getstream.io/cli.sh | bash
getstream skills stream-react-native

Once installed, invoke it from your agent:

/stream Add Stream Chat to my Expo app.

The /stream skill acts as a router, reading your request and dispatching it to the specialist skill. You can also invoke the /stream-react-native skill directly.

Stream Agent Skills can also be installed from skills.sh.

Getting started

This guide quickly brings you up to speed on using Stream’s Chat API before you move on and get started. The API is flexible and allows you to build any type of chat or messaging application.

The Stream Chat API client is available as an npm package and also available via yarn.

# using npm
npm install stream-chat

# using yarn
yarn add stream-chat

After installing the package, import the StreamChat module into your project, and you're ready to go:

import { StreamChat } from "stream-chat";

// or

const StreamChat = require("stream-chat").StreamChat;

Chat client

Let's get started by initialising the client and setting the current user:

const client = StreamChat.getInstance("{{ api_key }}");
// you can still use new StreamChat("api_key");

// Connect user to chat. This establishes a websocket connection between client and server.
await client.connectUser(
  {
    id: "jlahey",
    name: "Jim Lahey",
    image: "https://i.imgur.com/fR9Jz14.png",
  },
  "{{ chat_user_token }}",
);

// To disconnect a user
await client.disconnect();

The above snippet is for an in-browser or mobile integration. Server-side API calls are a little different, but this is covered in detail server side client documentation.

NOTE : Usage of StreamChat.getInstance() available since stream-chat-js@2.12.0. This new Singleton pattern allows you to instantiate a unique StreamChat client, i.e create a StreamChat instance and retrieve it wherever you need it on your app to perform API calls. After calling it once, any following getInstance( call will return the initial StreamChat instance. This will prevent you from accidentally creating multiple StreamChat instances, opening multiple WebSockets, and driving up your concurrent connections unnecessarily.

This new Chat client version is backward compatible. That means users can continue using new StreamChat() if they use an older version of the library or for any other reason.

Channels

Let’s continue by initialising your first channel. A channel contains messages, a list of people that are watching the channel, and optionally a list of members (for private conversations). The example below shows how to set up a channel to support chat for a group conversation:

// Create a channel using your own id for that channel.
const channel = client.channel('messaging', 'travel', {
  name: 'Awesome channel about traveling',
});

// OR create a channel by providing list of members for that channel.
// In this case, id will be auto-generated on backend side
const channel = client.channel('messaging', {
   members: ['vishal', 'neil']
  name: 'Awesome channel about traveling',
});

// fetch the channel state, subscribe to future updates
const state = await channel.watch();

As shown in code-snippet above, you can initialise a channel either by providing

  • ID for channel

  • OR list of members for channel. In this case, id will be auto-generated on backend for the channel. Please note that, you can't add or remove members from channel created using members list .

The channel type controls the settings we’re using for this channel.

There are 5 default types of channels:

  • livestream
  • messaging
  • team
  • gaming
  • commerce

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

The third argument is an object containing the channel data. You can add as many custom fields as you would like as long as the total size of the object is less than 5KB.

Please read more about channel operations at Channel docs.

Messages

Now that we have the channel set up, let's send our first chat message:

const text = "I’m mowing the air Randy, I’m mowing the air.";

const response = await channel.sendMessage({
  text,
  customField: "123",
});

Similar to users and channels, the  sendMessage  method allows you to add custom fields. When you send a message to a channel, Stream Chat automatically broadcasts to all the people that are watching this channel and updates in real-time. You can also add attachments to the message, please check our Messages docs for details.

Events

This is how you can listen to events on the client-side and update the UI for a channel dynamically:

// Listener for specific event on client
chatClient.on("user.presence.changed", (event) => {
  console.log("online presence changed for user - ", event.user);
});

// Listener for all events on client
chatClient.on((event) => {
  console.log("Received an event on client - ", event);
});

// Channel specific events
channel.on("message.new", (event) => {
  console.log("received a new message", event.message.text);
  console.log(
    `Now have ${channel.state.messages.length} stored in local state`,
  );
});

channel.on((event) => {
  console.log("received a new event", event);
});

You can receive the event and access the full channel state via channel.state .

Please read more about events at Event docs.

What's next

Now that you have basic understanding of the building blocks of our chat API, these are good places to go deeper: