# Overview

> **Info:** This is release candidate documentation for **Stream Chat React Native SDK v10**. For the latest stable version, see the [latest version (v9)](https://getstream.io/chat/docs/sdk/react-native/).

Stream Chat React Native is an SDK for chat on the Stream Chat API in React Native CLI and Expo apps: team and social messaging, livestream chat, customer support and similar apps.

It has two layers:

- **State** lives in `stream-chat`, the JavaScript client. Channels, threads, message lists and composers are objects that keep their data in reactive stores. You configure them through `client.config`.
- **UI** lives in `stream-chat-react-native-core`, which ships to apps as `stream-chat-react-native` for React Native CLI and `stream-chat-expo` for Expo. Its components read those stores and re-render when they change. You replace any of them through `WithComponents`.

Navigation is up to your app. The SDK renders a channel list, a channel and a thread, and tells you when the user picks a channel or opens a thread. Your navigator, such as React Navigation or Expo Router, decides which screen shows them.

To see the two layers work together, read [How the SDK is built](https://getstream.io/chat/docs/sdk/react-native/v10/getting-started/how-the-sdk-is-built/). It follows one message from the composer to the message list.

The SDK components cover:

- Channel lists, message lists and the message composer
- Threads, the thread list and quoted replies
- Reactions, mentions and slash commands
- Image, video and file attachments, with uploads and an image gallery
- Voice recordings and audio playback
- Polls and location sharing
- Read state, unread counts and typing indicators
- Search across channels, messages and users
- Offline storage with SQLite

## Start here

- [React Native tutorial](https://getstream.io/chat/sdk/react-native/tutorial/cli/): Build a working chat app from an empty project.
- [Quick start](https://getstream.io/chat/docs/sdk/react-native/v10/getting-started/quick-start/): Install the SDK and render your first chat screens.
- [How the SDK is built](https://getstream.io/chat/docs/sdk/react-native/v10/getting-started/how-the-sdk-is-built/): Follow one message through the state and UI layers.
- [Low-level client docs](https://getstream.io/chat/docs/react-native/): The stream-chat client API for connections, channels and messages.

## Build with Stream CLI and Agent Skills

The [Stream CLI](https://getstream.io/cli/docs/) and [Agent Skills](https://getstream.io/agent-skills/docs/) 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:

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

Once installed, invoke it from your agent:

```text
/stream Add Stream Chat to my React Native 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](https://www.skills.sh/getstream/agent-skills/stream).

## Best practices

- Start with the SDK's components and replace only the parts that need a different design.
- Use built-in features (threads, reactions, uploads, indicators) before building your own.
- Change behavior through `client.config`, and appearance through `WithComponents` and the theme. Both stay in place when you update the SDK.
- Install the package that matches your toolchain, `stream-chat-react-native` or `stream-chat-expo`, and never both.

## What's new in v10

v10 is an architectural release. The UI is largely unchanged. What moved is where state lives, how a channel list and a thread get on screen, and how the SDK is configured.

### State lives in the low-level client

Messages, channel lists, threads, search and the composer are owned by `stream-chat` objects, each holding a `StateStore`. Components subscribe to the part they render with `useStateStore`, so there is one source for any value and no copy kept in React.

For example, this badge shows the number of unread threads and updates when it changes:

```tsx
import { Text } from "react-native";
import type { ThreadManagerState } from "stream-chat";
import { useChatContext, useStateStore } from "stream-chat-react-native";

// Declared outside the component, so the subscription isn't recreated on every render.
const selector = (state: ThreadManagerState) => ({
  unreadThreadCount: state.unreadThreadCount,
});

export const UnreadThreadsBadge = () => {
  const { client } = useChatContext();
  const { unreadThreadCount } = useStateStore(client.threads.state, selector);

  return <Text>{unreadThreadCount} unread threads</Text>;
};
```

`TypingContext` and `PaginatedMessageListContext` are gone with it, and so are most of the values `ChannelContext`, `ThreadContext` and `ChannelsContext` used to hold. State is read from the instance, and actions are called on it. See [Reactive state](https://getstream.io/chat/docs/sdk/react-native/v10/state/state-and-entities/reactive-state/) and [Reading state in components](https://getstream.io/chat/docs/sdk/react-native/v10/ui/reading-state-in-components/).

### Pagination is a shared model

One `BasePaginator` backs channel lists, message history, thread replies, reminders and user groups, with cursors, ordering and loading state in one place. A `ChannelList` renders a `ChannelPaginator` that your app creates and registers on `client.channelManager`, which keeps every registered paginator in sync from a single set of WebSocket subscriptions, so several lists can coexist. The list's filters, sort and query options are set on the paginator, not on `ChannelList`. See [Channel list paginators](https://getstream.io/chat/docs/sdk/react-native/v10/state/loading-data/channel-list-paginators/).

### Threads render on their own

`Thread` is a component of its own, rendered next to `Channel` rather than inside it, and it takes a `Thread` instance from `stream-chat`. Your app keeps the open thread, for example in a navigation route, and renders `<Thread thread={thread}>` with a message list and a composer as its children. `Channel` and `Thread` each activate their channel or thread, with `Channel.activate()` or `Thread.activate()`, so the client knows which ones are on screen: it keeps them loaded and reloads them after a reconnect. See [Entity lifecycle](https://getstream.io/chat/docs/sdk/react-native/v10/state/state-and-entities/entity-lifecycle/).

### One place to configure instances

`client.config` is a configuration registry for the objects the SDK builds: channels, threads, composers, paginators and the client's own managers. It replaces the request-handler and throttling props that `Channel` used to take, and it is where a setup function goes when configuration values cannot express the customization. See [Configuration](https://getstream.io/chat/docs/sdk/react-native/v10/state/state-and-entities/configuration/).

### Localization by stable keys

Translation keys are namespaced identifiers rather than English sentences, with the copy inline at each call site. English is the only bundled language, and a partial custom dictionary is safe because an unsupplied key still renders.

Upgrading from v9 is covered in the [v10 upgrade guide](https://getstream.io/chat/docs/sdk/react-native/v10/release-guides/upgrade-to-v10/).

## Architecture

The two layers are two packages, and they meet in stores.

**State: `stream-chat`.** The client creates one `Channel` object per channel and one `Thread` object per thread. Each keeps its data in stores. For a channel, `channel.state` holds the members, read state and typing users, `channel.messagePaginator` holds the loaded messages, and `channel.messageComposer` holds what the user is writing. WebSocket events update these stores. You configure these objects through `client.config`. None of this depends on React.

**UI: `stream-chat-react-native`.** A component subscribes to the part of a store it shows, with `useStateStore`, and re-renders when that part changes. `Chat` gives every component below it the client, read with `useChatContext()`. `Channel` gives its children a channel and `Thread` a thread, read with `useChannel()` and `useThreadContext()`. `OverlayProvider`, above `Chat`, hosts the parts that draw over the whole screen: the message menu and the image gallery. You replace any component through `WithComponents`.

For example, when a new message arrives, `channel.messagePaginator` adds it to its store. `MessageList` subscribes to that store, so it re-renders with the new message. React keeps no copy of the messages.

The SDK ships as two packages, one per toolchain. Both re-export everything from `stream-chat-react-native-core` and register the native modules for their toolchain:

- `stream-chat-react-native` for React Native CLI apps.
- `stream-chat-expo` for Expo apps.

The AI components (streaming messages, Markdown, the AI composer) are a separate entry point of each package, `stream-chat-react-native/ai-components` and `stream-chat-expo/ai-components`, so an app that doesn't import them doesn't bundle them.

## Supported platforms

The SDK runs on iOS and Android. It needs React Native 0.79 or later with the [New Architecture](https://reactnative.dev/architecture/landing-page), and for Expo apps, Expo SDK 53 or later. Web isn't supported; use the [React SDK](https://getstream.io/chat/docs/sdk/react/) for web apps.

## Upgrading and versioning

The SDK follows [semantic versioning](https://semver.org/):

- Bug fixes and behavior improvements bump the **patch** version.
- New features bump the **minor** version.
- Incompatible API changes bump the **major** version.

Minor versions can include visual changes (spacing, colors, sizing) as the default UI evolves. Pin an exact version if you need visual stability.

## Sample apps

Sample apps live in the [`examples`](https://github.com/GetStream/stream-chat-react-native/tree/develop/examples) directory of the SDK repository: `SampleApp` for React Native CLI, `ExpoMessaging` for Expo, and `ExpoChatGPTSample` for the AI components.

## What's next

- [Installation](https://getstream.io/chat/docs/sdk/react-native/v10/getting-started/installation/): Add stream-chat-react-native or stream-chat-expo to your app.
- [State layer](https://getstream.io/chat/docs/sdk/react-native/v10/state/state-and-entities/reactive-state/): How the stores hold state and notify subscribers.
- [Upgrade to v10](https://getstream.io/chat/docs/sdk/react-native/v10/release-guides/upgrade-to-v10/): Move an app from v9 to v10.

## FAQ

**How do I upgrade from v9?**

Follow the [v10 upgrade guide](https://getstream.io/chat/docs/sdk/react-native/v10/release-guides/upgrade-to-v10/).

**How do I enable offline support?**

It's opt-in: install `@op-engineering/op-sqlite` and set `enableOfflineSupport` on `Chat`. See [Offline support](https://getstream.io/chat/docs/sdk/react-native/v10/state/offline-support/offline-support/). Expo Go can't run it; use a development build.

**Does chat include moderation?**

Yes. AI engines screen messages and users can flag content into a [dashboard](https://getstream.io/signin/?product=chat) review queue. See [moderation for chat](https://getstream.io/chat/docs/react-native/moderation/).

---

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