# Client

Stream Chat for React Native uses the [Stream Chat client](https://github.com/GetStream/stream-chat-js) to connect to and communicate with the Stream API.

The full [JavaScript client docs](/chat/docs/javascript/) should be referenced for detailed information on directly using the client.

## Setup

To interact with the Stream Chat API you must create a client instance and connect to the API, usually as an authenticated user.

### Instantiation

The Stream Chat client, `StreamChat` is a dependency of `stream-chat-react-native` and can be imported from `stream-chat`.
To create a client instance you can call `getInstance` on the client and provide and API key.

```ts
import { StreamChat } from "stream-chat";

const client = StreamChat.getInstance("api_key");
```

<admonition type="warning">

**Usage of `StreamChat.getInstance()` available since stream-chat@2.12.0.**

<br />
This new Singleton pattern allows you to instantiate a unique StreamChat client, i.e create a StreamChat instance and
retrieve it wherever you need it on your app to perform API calls. After calling it once, any following <code>
  getInstance
</code> call will return the initial StreamChat instance. This will prevent you from accidentally creating multiple
StreamChat instances, opening multiple WebSockets, and driving up your concurrent connections unnecessarily.
<br />
<br />

Stream Chat is backward compatible. Users can continue using <code>new StreamChat()</code> if desired.

<br />

```ts
const client = new StreamChat("api_key");
```

Calling <code>new StreamChat()</code> repeatedly will create new copies of the client and in turn new WebSocket connections when <code>connectUser</code> is called.
If you are using <code>new StreamChat()</code> you need to be vigilant about your use to ensure you are not creating multiple WebSocket connections unnecessarily.

</admonition>

### Connecting a User

To connect a user a the `connectUser` function should be called and provided with the user object and `user_token`.
The `user_token` is typically sent from your back end when a user is authenticated.

```ts
await client.connectUser(
  {
    id: "testUser",
    name: "Test User",
  },
  "user_token",
);
```

It is recommended to not repeatedly call `connectUser` unnecessarily, multiple calls to `connectUser` will result in warnings, and attempting to call `connectUser` before disconnecting a current user will throw an Error.

## UI Components

The Stream Chat for React Native UI components handle most interactions with the client for you after connecting with an authenticated user.

### Providing the Client to the UI

To provide the client to the UI components you simply provide the client instance as the prop `client` to the `Chat` component.

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

const client = StreamChat.getInstance("api_key");

export const Screen = () => (
  <Chat client={client}>{/** App components */}</Chat>
);
```

The Stream Chat for React Native UI components then handle interacting with the client internally by accessing the client via [`context`](https://reactjs.org/docs/context.html).

<admonition type="note">

If you are customizing certain components or functionality you may have to interact with the client as well.
You can access the client provided to the `Chat` component internally via the `useChatContext`.

<br />

```ts
import { useChatContext } from "stream-chat-react-native";

const { client } = useChatContext();
```

</admonition>

### Using UI Functions

The UI provides a number of functions that interact with the client while keeping the UI state in sync using `context`.
The [contexts section](/chat/docs/sdk/react-native/v3/contexts/attachment-picker-context/) details what functions are accessible.
When customizing your application you should ensure you are utilizing the correct functions to keep the UI state up to date.

The `sendMessage` function for instance, provided by `useMessageInputContext`, is not the same as the `sendMessage` function found directly on a `channel` in the client.
Therefore calling `channel.sendMessage(messageData)` will not result in a message optimistically showing in the UI, or a failed send state, instead the message will not show until it is returned by the server.

<admonition type="warning">

You should not assume any function directly called on the client will result in a UI update.
The UI state is managed internally by the components and `context`, most client interactions require an event returned by the server to update the UI.

</admonition>

## Accessing the Client Instance

There are multiple ways to access the client instance throughout your application.
[As mentioned](#providing-the-client-to-the-ui) you can access the `client` via `useChatContext` when inside the `Chat` component.
This works well if you can wrap your entire application in a single `Chat` component and have the `StreamChat` instance provided throughout your app via the internal `context`.
But if you have multiple screens that contain `Chat` components where a client instance is necessary you will need to access the shared instance in other ways.

You can store the client in a [`context`](https://reactjs.org/docs/context.html) you create yourself.
Create your own custom class that provides it.
Or using the Singleton structure you can call `getInstance` when required to always be returned the current instance if one exists, or create a new one otherwise.

<admonition type="warning">

Do not create and connect multiple instances using `new StreamChat()`, this will result in multiple `StreamChat` instances and opening multiple WebSocket connections.

</admonition>

## Direct Interaction

There may be some direct interaction with the client that is required for your application.
Referring to the [full documentation](/chat/docs/javascript/) is suggested for detailed information on client functionality.
Common interactions with the client used in conjunction with the Stream Chat for React Native components have been included for convenience.

### Creating a Channel

A channel must be initialized with either an `id` or a list of members for the channel.
If you provide a list of members an `id` will be auto-generated on backend for the channel.

<admonition type="note">

You can't add or remove members from channel created using a list of members.

</admonition>

<tabs>

<tabs-item value="channelId" label="Channel Id">

```ts
/**
 *  Channel created using a channel id
 */
const channel = client.channel(channel_type, "channel_id", {
  name: "My New Channel",
});
```

</tabs-item>

<tabs-item value="members" label="Members List">

```ts
/**
 *  Channel created using a members list
 */
const channel = client.channel(channel_type, {
    members: ['userOne', 'userTwo']
    name: 'My New Channel',
});
```

</tabs-item>

</tabs>

To create a channel on the server you must call `create` or `watch` on a new channel instance.
`create` will create the channel while `watch` will both create the channel and subscribe the client to updates on the channel.

<tabs>

<tabs-item value="watch" label="watch">

```ts
await channel.watch();
```

</tabs-item>

<tabs-item value="create" label="create">

```ts
await channel.create();
```

</tabs-item>

</tabs>

### Disconnecting a User

To disconnect a user you can call `disconnect` on the client.

```ts
await client.disconnectUser();
```


---

This page was last updated at 2026-04-22T16:42:54.311Z.

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