Installation

Install the SDK in a few steps:

Best Practices

  • Choose RN CLI vs Expo tabs based on your app runtime; don't mix dependencies across runtimes.
  • Install only the optional features you need to keep bundle size and native setup lean.
  • Add required platform permissions as you enable features (audio, camera, media library).
  • Follow each dependency’s post-install steps to avoid runtime errors.
  • Keep Reanimated/Worklets Babel plugin last and wrap the app in GestureHandlerRootView.

Prerequisites

Set up the React Native development environment: React Native guide.

For Expo, follow this guide.

Add Stream Chat SDK and peer dependencies

Install the SDK:

yarn add stream-chat-react-native

Install peer dependencies:

yarn add @react-native-community/netinfo react-native-gesture-handler react-native-reanimated react-native-worklets react-native-svg

Installed packages:

Opt-in features

Optional features require additional dependencies.

Video playing

yarn add react-native-video

Voice recording and audio attachments

yarn add react-native-audio-recorder-player react-native-blob-util

Configuring permissions

An example AndroidManifest.xml would look like this with permissions:

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

An example Info.plist would look like this with permissions:

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

Attachment sharing

Share attachments outside the app.

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

Haptic feedback

Provide haptic feedback to the user.

yarn add react-native-haptic-feedback

Copy message

Copy the text message content to the clipboard.

yarn add @react-native-clipboard/clipboard

Share file attachments

Share files from the device.

yarn add @react-native-documents/picker

Capture image and upload attachment

Capture images from the camera and upload them.

yarn add react-native-image-picker

Configuring permissions

On Android, an example AndroidManifest.xml would look like this with permissions:

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

On iOS, an example Info.plist would look like this with permissions:

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

Pick image using Native Image Picker

Pick gallery images using the native picker and upload them.

yarn add react-native-image-picker

Configuring permissions

On Android, no permissions are required.

On iOS, an example Info.plist would look like this with permissions:

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

Built-in image media library

Pick images using the built-in media library and upload them.

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

Configuring permissions

An example AndroidManifest.xml would look like this with permissions:

<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" />
  <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

An example Info.plist would look like this with permissions:

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

Offline support

Enable offline support.

yarn add @op-engineering/op-sqlite

High-performance message list

For better performance with large message lists, you can use @shopify/flash-list instead of the default FlatList. This is especially useful for channels with thousands of messages.

yarn add @shopify/flash-list

See the FlashList documentation for more information on using FlashList with the SDK.

The overall installation of the optional dependencies would look like this:

Follow each dependency's setup instructions to ensure proper integration.

Additional Steps

Some dependencies require extra app configuration:

module.exports = {
  presets: [
    ... // don't add it here :)
  ],
  plugins: [
    ...
    'react-native-reanimated/plugin',
  ],
};

react-native-reanimated/plugin has to be listed last.

If you are using react-native-reanimated version >=4.0.0, you can replace the react-native-reanimated/plugin with react-native-worklets/plugin in your application's babel.config.js.

module.exports = {
  presets: [
    ... // don't add it here :)
  ],
  plugins: [
    ...
    'react-native-worklets/plugin',
  ],
};

Read more here.

  • After installation, wrap your entry point with <GestureHandlerRootView> or gestureHandlerRootHOC:
import { GestureHandlerRootView } from "react-native-gesture-handler";

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

Your entry point is usually index.js or App.tsx. For Expo Router v3.x, use app/_layout.js.

Please also follow the steps mentioned in the links below for corresponding dependencies:

Run the app:

npx pod-install
yarn ios