Skip to main content
Version: v5

Going Live Checklist

Before going live, make sure you go through this checklist to have a smooth launch of Stream Chat React Native chat SDK in your app.

Usage of Tokens

To quickly get started with the chat SDK, you can use development tokens.

Development tokens disable token authentication and use client-side generated tokens or a manually generated static token.

They are not suitable for production usage. Therefore, it's important that you use a proper authentication mechanism before you release your app.

For additional security, we recommend using tokens with expiry date, and our token provider mechanism for refreshing tokens.

Sensitive Data Storage

Sensitive data like your Stream secret should not be stored locally in your app.

It can be accessed with some tools on jail broken devices by attackers. If an attacker has your secret, they can do many destructive actions to your app instance.

Logging out

Our SDKs use persistent storage, for offline support that is optional for users to integrate.

If you have a logout method in your app, the local storage should be cleared out. If you don't wait for the completion handler of the logout method to be finished, and you try logging in with a different user, you might get into a corrupted state and a potential crash.

Therefore, it's important to do any other action after the logout has completed, as shown here:

import { QuickSqliteClient } from 'stream-chat-react-native';

const logout = async () => {
// Reset and clear the local database if offline storage was enabled.

// Disconnect the connected user for the chat client.

// Set the current chat client to null.

Performance for Custom components

If a value in a context updates all components accessing values from that context will re-render, even if the values they are accessing have not changed.

Our default components use memoization with custom areEqual checks to ensure components are only being re-rendered when necessary. This is most important inside of messages where the largest performance hit would be noticeable as an update that re-renders every message is computationally expensive.

When creating custom components, we suggest you to take the same performance consideration to ensure the user experience is not degraded.

Eg: Adding a console log to a custom DateHeader component that is accessing the PaginatedMessageListContext a large number of re-renders can be seen when the channel mounts, and re-renders continue when interacting with messages, such as reacting to one.

import { usePaginatedMessageListContext } from 'stream-chat-react-native';
import { Text } from 'react-native';

const MySenderComponent = () => {
const { messages } = usePaginatedMessageListContext();
const latestMessageSender = messages[messages.length - 1]?.user?.name;

return <Text>{`Last Sender: ${latestMessageSender}`}</Text>;

To reduce these re-renders the component can be broken apart into a component that consumes context, and a component that is memoized and takes only props. A custom areEqual check can then be used in the memoization to determine if the component should re-render.

import React from 'react';
import { usePaginatedMessageListContext } from 'stream-chat-react-native';
import { Text } from 'react-native';

const MySenderComponentWithContext = ({ latestMessageSender }) => {

return <Text>{`Last Sender: ${latestMessageSender}`}</Text>;

const MemoizedMySenderComponent = React.memo(
(prev, next) => prev.latestMessageSender === next.latestMessageSender,

const MySenderComponent = () => {
const { messages } = usePaginatedMessageListContext();
const latestMessageSender = messages[messages.length - 1]?.user?.name;

return <MemoizedMySenderComponent latestMessageSender={latestMessageSender} />;

Following this pattern MySenderComponentWithContext, and therefore the UI component Text, render only one time, on mount. The check on latestMessageSender will ensure the component re-renders only when latestMessageSender changes, but otherwise will not.

Did you find this page helpful?