# Offline Support

The React Native Chat SDK provides offline support (opt-in). Users can access and interact with chat when the network is unavailable.

<admonition type="note">

Integration with Expo is possible using the `expo-dev-client` library. Offline support cannot be used in the "Expo Go" app, because it requires custom native code.

</admonition>

## Best Practices

- Enable offline support early in app startup to populate local state.
- Don’t block UI on `connectUser`; render and let the client sync.
- Reset the offline database on sign-out to avoid cross-user data leaks.
- Keep queued actions minimal and surface retry states in the UI.
- Replace `ImageComponent` with a caching implementation for reliable offline media.

## Offline Support V2

In `7.1.0+`, offline support moved into the `StreamChat` client for better performance and ergonomics.

The full list of changes is [here](https://github.com/GetStream/stream-chat-react-native/v8/pull/3096). If you use offline support, upgrade to this version. No migration steps are required; just update the SDK and ensure `stream-chat >= 9.2.0` if installed separately.

## Features

The offline storage implementation currently offers the following features:

- Access to chat when Internet connection is disabled or low.
- Faster startup times and loading, since initial data is loaded from offline storage before performing any network requests.
- Syncing of the offline database using WebSocket events and Sync API.
- Optimistic offline updates during actions (send message, add reaction, etc.)
- Queueing certain actions for retry after reconnect

The following features are currently **NOT** implemented. They will be implemented gradually as part of future releases.

- Access to threads in offline mode.

## Enabling Offline Support

To enable offline support:

### Add `@op-engineering/op-sqlite` dependency

> Check the version compatibility table to ensure your `@op-engineering/op-sqlite` version matches your `stream-chat-react-native` version.

```bash
  yarn add @op-engineering/op-sqlite
  npx pod-install
```

### Do not wait for `connectUser` call to succeed

Call `connectUser` before rendering chat components, but do not wait for it to resolve. This ensures:

- Chat components have access to current user information, which is important to store/access offline data.
- In case of slow or no network access, Chat components will still load the chat data without waiting for `connectUser` to succeed.

```tsx
const chatClient = StreamChat.getInstance("API_KEY");
const App = () => {
  const [isClientReady, setIsClientReady] = useState(false);

  useEffect(() => {
    const startChat = async () => {
      const connectPromise = chatClient.connectUser(user, tokenOrTokenProvider);
      setIsClientReady(true); // this allows components to render
      await connectPromise;
      // Any other post-connectUser logic you may have goes here.
    };
    startChat();
  }, []);

  if (!isClientReady) return null; // or some loading indicator;

  return (
    <Chat client={chatClient} enableOfflineSupport>
      ...
    </Chat>
  );
};
```

#### Add `enableOfflineSupport` prop on `Chat` component

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

<Chat client={chatClient} enableOfflineSupport>
  ...
</Chat>;
```

#### Reset the database on sign-out

Since the SDK doesn't handle app-level authentication logic, it's the application's responsibility to ensure the database is reset when a user gets logged out. This should generally be done before you call `client.disconnectUser()`.

```tsx
// Sign out logic (recommended approach for v8+)
await chatClient.offlineDb.resetDB();
await chatClient.disconnectUser();
```

<admonition type="info">

Since version `7.1.0`, the offline support API has been moved to the low level client. The legacy `SqliteClient.resetDB()` approach still works but using `chatClient.offlineDb.resetDB()` is the recommended approach.

</admonition>

## Events Recovery

When the app is backgrounded or offline, other users may perform actions.

The SDK fetches and processes events since your last online session when you foreground the app.

No extra work required.

## Queued Offline Actions

If the device loses connection during an action (send, react, delete), it fails initially but is retried automatically after reconnect.

Queued actions persist across app restarts and OS kills. Actions queued while fully offline also work.

These are the actions that support offline queuing:

- Send message (version `7.1.0` and above)
- Delete message
- Add reaction
- Delete reaction
- Create draft (version `8.0.0` and above)
- Delete draft (version `8.0.0` and above)

## How To Cache Images

<admonition type="info">

Available since version `5.3.0`.

</admonition>

The SDK uses React Native's default image caching, which can be unreliable offline. You can replace all internal [`Image`](https://reactnative.dev/docs/next/image) usage via the `ImageComponent` prop on `Chat` with a caching-enabled component that matches the `Image` API.

There are plenty of libraries available for this purpose:

- [`react-native-fast-image`](https://www.npmjs.com/package/react-native-fast-image)
- [`react-native-progressive-fast-image`](https://www.npmjs.com/package/@freakycoder/react-native-progressive-fast-image)
- [`react-native-cached-image`](https://www.npmjs.com/package/react-native-cached-image)

<admonition type="note">

Due to technical limitations, viewing images in full screen (image viewer) in offline mode is not currently supported.

</admonition>

Example using `react-native-fast-image`:

```tsx
import FastImage from "react-native-fast-image";

...

<Chat
  client={chatClient}
  enableOfflineSupport
  ImageComponent={FastImage}
/>
```


---

This page was last updated at 2026-04-17T17:33:45.331Z.

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