Info:
This is release candidate documentation for Stream Chat React Native SDK v10. For the latest stable version, see the latest version (v9).

Installation

Install the SDK package for your toolchain, its peer dependencies, and stream-chat, the JavaScript client that holds the state. stream-chat-react-native and stream-chat-expo 10 and stream-chat 10 are release candidates, published under the rc tag. The SDK needs stream-chat 10.0.0-rc.26 or later.

The SDK needs React Native 0.79 or later with the New Architecture, and for Expo apps, Expo SDK 53 or later. stream-chat 10 needs Node 22.18 or later to install.

Install the SDK

Terminal
yarn add stream-chat-react-native@rc stream-chat@rc

The SDK depends on stream-chat itself. Your app imports from it too, for example ChannelPaginator and the types, so add it to your app at the version the SDK uses. Exactly one copy must resolve: a second copy makes the client and the objects your app creates come from different classes.

Then install the peer dependencies:

Terminal
yarn add @react-native-community/netinfo react-native-gesture-handler react-native-reanimated react-native-worklets react-native-teleport react-native-svg react-native-safe-area-context
Note:

react-native-teleport and several optional packages below are native modules. After adding one, rebuild the app: run npx pod-install for React Native CLI, or npx expo prebuild for an Expo app that uses prebuild.

Configure the app

Add the Babel plugin of react-native-reanimated to babel.config.js, as the last plugin. With react-native-reanimated 4, the plugin is react-native-worklets/plugin:

babel.config.js
module.exports = {
  presets: [
    // your presets
  ],
  plugins: [
    // your other plugins
    "react-native-worklets/plugin",
  ],
};

With react-native-reanimated 3, use react-native-reanimated/plugin instead. See the Reanimated installation guide.

Wrap the root of your app in GestureHandlerRootView:

App.tsx
import { GestureHandlerRootView } from "react-native-gesture-handler";

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      {/* the rest of the app */}
    </GestureHandlerRootView>
  );
}

For Expo Router, the root is app/_layout.tsx.

To build a first app, continue with the Quick start.

Best practices

  • Install stream-chat next to the SDK and upgrade them together. The SDK depends on newer client features, so mismatched versions can fail at runtime even if installation succeeds.
  • Use the package that matches your toolchain, and never install both.
  • Install only the optional features you need. Each one adds a native module.
  • Add the platform permissions a feature needs (microphone, camera, photo library) when you add it.
  • Keep a single copy of dayjs (the SDK uses ^1.11.23). If your app declares dayjs too, use a compatible range.

Optional features

Each feature below turns on when its package is installed. Without the package, the SDK leaves the feature out.

Video playback

Terminal
yarn add react-native-video

Voice recording and audio playback

Terminal
yarn add react-native-nitro-sound react-native-nitro-modules react-native-blob-util

react-native-nitro-sound records and plays audio. react-native-audio-recorder-player still works in its place, but it's deprecated. react-native-blob-util reads and writes the recorded files.

Add the microphone permission. On Android, in AndroidManifest.xml:

<uses-permission android:name="android.permission.RECORD_AUDIO" />

On iOS, in Info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your microphone for voice recording.</string>

Voice recording is off until you turn it on with the audioRecordingEnabled prop of Channel and Thread.

Sharing attachments

Share an attachment to another app.

Terminal
yarn add react-native-blob-util react-native-share

Haptic feedback

Terminal
yarn add react-native-haptic-feedback

Copying messages

Copy a message's text to the clipboard from the message menu.

Terminal
yarn add @react-native-clipboard/clipboard

Picking files

Attach files from the device.

Terminal
yarn add @react-native-documents/picker

Taking photos and using the system image picker

Take a photo with the camera, or pick images with the system picker.

Terminal
yarn add react-native-image-picker

Add the camera permission. On Android, in AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />

On iOS, in Info.plist, add the camera permission, and the photo library permission for the system picker:

<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your camera to share an image in a message.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME) would like access to your photo library to share an image in a message.</string>

Built-in media library

Pick photos and videos from the attachment picker's own grid instead of the system picker.

Terminal
yarn add @react-native-camera-roll/camera-roll

Add the permissions. On Android, in AndroidManifest.xml:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" />

The SDK asks for READ_MEDIA_IMAGES and READ_MEDIA_VIDEO on Android 13 and later, and for READ_EXTERNAL_STORAGE on earlier versions. It only reads the library, so it doesn't need WRITE_EXTERNAL_STORAGE.

On iOS, in Info.plist:

<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME) would like access to your photo library to share an image in a message.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>$(PRODUCT_NAME) would like to save photos to your photo library after downloading them from a message.</string>
Note:

Google Play's photo and video permissions policy allows READ_MEDIA_IMAGES and READ_MEDIA_VIDEO only for apps that need broad access to the user's photos and videos. An app that doesn't qualify leaves the built-in media library out. It doesn't install @react-native-camera-roll/camera-roll or expo-media-library, and doesn't declare those permissions. In an Expo app, list them under android.blockedPermissions in app.json, which also removes them when another package adds them. With react-native-image-picker or expo-image-picker installed, the attachment picker's photo button then opens the system picker, which needs no Android permission.

Offline support

Keep channels and messages in a local SQLite database, so the app shows them before it connects and queues what the user does while offline.

Terminal
yarn add @op-engineering/op-sqlite

Then set enableOfflineSupport on Chat. See Offline support.

FlashList message list

MessageFlashList renders the message list with @shopify/flash-list 2.1 or later, in place of MessageList, which uses FlatList.

Terminal
yarn add @shopify/flash-list

Entry points

Each package has two entry points:

Part RN CLI Expo
Components, contexts and hooks stream-chat-react-native stream-chat-expo
AI components: streaming messages, Markdown, the AI composer stream-chat-react-native/ai-components stream-chat-expo/ai-components

Metro doesn't drop unused code, so the AI components are kept out of the main entry point: an app that never imports ai-components doesn't bundle them. It imports @shopify/react-native-skia and victory-native for its charts, so an app that imports ai-components installs both, and its dictation is compiled into the iOS app only when you turn it on. See AI integrations.