---
source_url: https://www.pubnub.com/docs/chat/chat-sdk/build/configuration
title: Initial configuration
updated_at: 2026-06-04T11:08:58.643Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Initial configuration

Initialize and configure the Chat SDK before building your chat app.

## Prerequisites

1. [Sign in](https://admin.pubnub.com/#/login) or [create an account](https://admin.pubnub.com/#/register) on the Admin Portal.
2. [Create an app](https://www.youtube.com/watch?v=ou5RMN1LQ1Y&t=19s&ab_channel=PubNub) to get your **Publish Key** and **Subscribe Key**.

:::warning Limit of 3 keysets for Free tier accounts
Effective February 3, 2025, all [Free tier](https://www.pubnub.com/pricing/) accounts are limited to a maximum of three keysets. If your account exceeds this limit, you must delete existing keysets to create new ones.
:::

A new app receives demo keys automatically. You can create multiple keysets per app. Use separate keysets for production and test environments.

:::warning Required keyset settings
Enable these features on your keyset in the Admin Portal:
* **App Context** - Store user and channel data
* **Presence** - Track online/offline status
* **Message Persistence** - Store message history
:::

## Download the SDK

The JavaScript Chat SDK is available as the `@pubnub/chat` package. You can install it using a package manager or load it directly from the PubNub CDN.

### Package manager

Install the `@pubnub/chat` package using npm, yarn, pnpm, or bun:

```bash
npm install @pubnub/chat
```

```bash
yarn add @pubnub/chat
```

```bash
pnpm add @pubnub/chat
```

```bash
bun add @pubnub/chat
```

### CDN

Alternatively, include the SDK directly in your HTML by referencing the PubNub CDN:

```html
<script src="https://cdn.pubnub.com/sdk/js-chat/pubnub-chat.1.0.1.js"></script>
```

The JavaScript Chat SDK is also available on [GitHub](https://github.com/pubnub/kmp-chat/tree/master/js-chat).

## Initialize PubNub

Use the `init()` method to create a Chat SDK instance. Three parameters are required: `publishKey`, `subscribeKey`, and `userId`.

Optional parameters configure features like typing indicators, presence tracking, push notifications, and rate limiting.

:::note Extended configuration
The Chat SDK supports all [JavaScript SDK configuration options](https://www.pubnub.com/docs/sdks/javascript/api-reference/configuration#initialization). For example, use `authKey` with [Access Manager](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/permissions) for production apps. See [Additional configuration options](#additional-configuration-options) for details.
:::

### Method signature

```ts
const chat = Chat.init({
    publishKey: string,
    subscribeKey: string,
    userId: string,
    authKey?: string,
    typingTimeout?: number,
    storeUserActivityInterval?: number,
    storeUserActivityTimestamps?: boolean,
    pushNotifications?: {
      sendPushes?: boolean,
      deviceToken?: string,
      deviceGateway?: "apns2" | "gcm",
      apnsTopic?: string,
      apnsEnvironment?: "development" | "production"
    },
    rateLimitFactor?: number,
    rateLimitPerChannel?: {
      direct?: number,
      public?: number,
      group?: number,
    },
    errorLogger?: ErrorLoggerImplementation,
    customPayloads?: {
      getMessagePublishBody?: (m: TextMessageContent, channelId: string) => any,
      getMessageResponseBody?: (m: MessageDTOParams) => TextMessageContent,
      editMessageActionName?: string,
      deleteMessageActionName?: string,
      reactionsActionName?: string
    },
    cryptoModule?: CryptoModule.aesCbcCryptoModule({cipherKey})
    syncMutedUsers?: boolean
    emitReadReceiptEvents?: { [key in ChannelType]?: boolean }
}): Promise<Chat>
```

### Input parameters

| Parameter | Feature | Description |
| --- | --- | --- |
| publishKey | string | Yes |  | [Send messages](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/send-receive) | Specifies the key used to publish messages on a channel. |
| subscribeKey | string | Yes |  | [Receive messages](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/send-receive) | Specifies the key used to subscribe to a channel. |
| userId | string | Yes |  | n/a | [Unique User ID](https://www.pubnub.com/docs/general/setup/users-and-devices) that becomes your app's current user. It's a string of up to 92 characters that identifies a single client (end user, device, or server) that connects to PubNub. Based on User ID, PubNub calculates pricing for your apps' usage. User ID should be persisted and remain unchanged. If you don't set `userId`, you won't be able to connect to PubNub. |
| authKey | string | Optional |  | n/a | If [Access Manager](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/permissions) is utilized, the client will use this `authKey` to authenticate restricted requests. |
| typingTimeout | number | Optional | `5000` | [Typing Indicator](https://www.pubnub.com/docs/chat/chat-sdk/build/features/channels/typing-indicator) | Specifies the default timeout after which the [typing indicator](https://www.pubnub.com/docs/chat/chat-sdk/build/features/channels/typing-indicator) automatically stops when no typing signals are received. The default and maximum value is set to `5000` milliseconds (5 seconds). |
| storeUserActivityTimestamps | boolean | Optional | `false` | [User's last online activity, global presence](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/presence#global-presence) | Specifies if you want to track the user's [global presence](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/presence#global-presence) in your chat app. The user's activity is tracked through the [lastActiveTimestamp](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/user) parameter on the `User` object. |
| storeUserActivityInterval | number | Optional | `600000` | [User's last online activity, global presence](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/presence#global-presence) | Specifies how often the user global presence in the app should be updated. Requires `storeUserActivityTimestamps` to be set to `true`. The default value is set to `600000` milliseconds (10 minutes), and the minimum possible value is `60000` milliseconds (1 minute). If you try to set it to a lower value, you'll get the `storeUserActivityInterval must be at least 60000ms` error. |
| pushNotifications | object | Optional |  | [Push Notifications](https://www.pubnub.com/docs/chat/chat-sdk/build/features/push-notifications) | List of parameters you must set if you want to enable sending/receiving [mobile push notifications](https://www.pubnub.com/docs/chat/chat-sdk/build/features/push-notifications) for iOS and Android devices, either through Apple Push Notification service (APNS) in version 2 or Firebase Cloud Messaging (FCM), formerly known as Google Cloud Messaging (GCM). |
| > sendPushes | boolean | Optional | `false` | as above | The main option for enabling sending notifications. It must be set to `true` if you want a particular client (whether a mobile device, web browser, or server) to send push notifications to mobile devices. These push notifications are messages with a provider-specific payload (different for APNs and FCM) that the Chat SDK automatically attaches to every message. Chat SDK includes a [default payload setup](https://www.pubnub.com/docs/chat/chat-sdk/build/features/push-notifications) for APNs and FCM gateways in every message sent to the registered channels. This is the only required option to enable if you want to send push notifications to Android devices. For iOS devices, you also have to configure `apnsTopic`. |
| > deviceToken | string | Optional |  | as above | Option for receiving notifications on iOS and Android devices. A device token refers to the unique identifier assigned to a specific mobile device by a platform's push notification service. It targets and delivers push notifications to the intended app on that specific device. Suppose you don't set this option and try to run [channel registration-related methods](https://www.pubnub.com/docs/chat/chat-sdk/build/features/push-notifications#register-selected-push-channels). In that case, you'll get the `Device Token has to be defined in Chat pushNotifications config` error. Refer to the official [Apple](https://developer.apple.com/documentation/usernotifications/registering_your_app_with_apns#2942135) and [Google](https://firebase.google.com/docs/cloud-messaging/ios/client) docs to learn how to obtain a device token for the APNs and FCM services. |
| > deviceGateway | apns2 | Optional | `gcm` | as above | Option for receiving push notifications on Android (`gcm`) or iOS (`apns2`) devices. |
| > apnsTopic | string | Optional |  | as above | An Apple specific-option for sending and receiving notifications. This string is a [bundle ID](https://help.apple.com/xcode/mac/current/#/deve70ea917b) that you must define yourself for your iOS app so that Apple could [enable push notifications](https://help.apple.com/xcode/mac/current/#/devdfd3d04a1) for it in APNs. The string takes the following format: `com.domainname.applicationname`. Apple combines that ID with your Team ID (generated by Apple) and creates an [App ID](https://help.apple.com/xcode/mac/current/#/dev618af4e67) for your application. To send pushes from an iOS device, you must also set `sendPushes` to `true`. To receive pushes on an iOS device, you must also set `deviceGateway` to `apns2`, define `deviceToken`, and `apnsEnvironment`. Suppose you don't configure `apnsTopic`, but set `deviceGateway` to `apns2`. In that case, you'll get the `apnsTopic has to be defined when deviceGateway is set to apns2` error and Chat SDK won't attach the `apns` payload to messages. |
| > apnsEnvironment | development | Optional | `development` | as above | Option for receiving notifications on iOS devices. When registering for push notifications, this option specifies whether to use the development or production [APNs environment](https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment). |
| rateLimitFactor | number | Optional | `2` | [Client-side rate limiting](#client-side-rate-limiting) | The so-called ["exponential backoff"](https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/) which multiplicatively decreases the rate at which messages are published on channels. It's bound to the `rateLimitPerChannel` parameter and is meant to prevent message spamming caused by excessive retries. The default value of `2` means that if you set `rateLimitPerChannel` for direct channels to `1000` (one second) and try to send three messages on such a channel type within the span of one second, the second message will be published one second after the first one (just like the `rateLimitPerChannel` value states), but the third one will be published two seconds after the second one, meaning the publishing time is multiplied by `2`. |
| rateLimitPerChannel | object | Optional |  | [Client-side rate limiting](#client-side-rate-limiting) | Client-side limit (expressed in milliseconds) that states the rate at which messages can be published on a given channel type. Its purpose is to prevent message spamming in your chat app. This parameter takes an object with these three parameters: `direct`, `group`, and `public`. For example, if you decide that messages on all `direct` channels must be published no more often than every second, set this parameter to `1000`, like `rateLimitPerChannel { direct: 1000 }`. |
| > direct | number | Optional | `0 (no limit)` | as above | Rate set on all direct (1:1) channels at which messages can be published. |
| > group | number | Optional | `0 (no limit)` | as above | Rate set on all group channels at which messages can be published. |
| > public | number | Optional | `0 (no limit)` | as above | Rate set on all public channels at which messages can be published. |
| errorLogger | ErrorLoggerImplementation | Optional | `ErrorLoggerImplementation { setItem(key: string, params: ErrorLoggerSetParams): void, getStorageObject(): Record<string, unknown> }` | [Error logging](https://www.pubnub.com/docs/chat/chat-sdk/build/features/error-logging) | Specifies if any Chat SDK-related errors should be logged. It's enabled by default. The `setItem` method specifies where errors should be saved and the `getStorageObject` method returns an object with a list of errors. You can replace this implementation with your own. |
| customPayloads | object | Optional |  | [Send and receive messages](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/send-receive) | Property that lets you define your custom message payload to be sent and/or received by Chat SDK on one or all channels, whenever it differs from the default `message.text` Chat SDK payload. It also lets you configure your own message actions whenever a message is edited or deleted. For examples, check [Custom payload](https://www.pubnub.com/docs/chat/chat-sdk/build/configuration#custom-payload). |
| > getMessagePublishBody | Function | Optional |  | as above | Function that lets Chat SDK send your custom payload structure. It defines the structure of your own message payload's body (of `any` type) that you're sending through PubNub. Expand the [Message-related types](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message#properties) section for more details on the required `TextMessageContent` structure. Define `getMessageResponseBody` whenever you use `getMessagePublishBody`. |
| > getMessageResponseBody | Function | Optional |  | as above | Function that lets Chat SDK receive your custom payload structure. Use it to let Chat SDK translate your custom message payload into the default Chat SDK message format (defined in `TextMessageContent`). Expand the [Message-related types](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message#properties) section for more details on the required `TextMessageContent` structure. Define `getMessagePublishBody` whenever you use `getMessageResponseBody`. |
| > editMessageActionName | string | Optional |  | as above | A type of action you want to be added to your [Message](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message) object whenever a published message is edited, like `"changed"` or `"modified"`. The default message action used by Chat SDK is `"edited"`. Expand the [Message-related types](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message#properties) section for more details. |
| > deleteMessageActionName | string | Optional |  | as above | A type of action you want to be added to your [Message](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message) object whenever a published message is deleted, like `"removed"`. The default message action used by Chat SDK is `"deleted"`. Expand the [Message-related types](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message#properties) section for more details. |
| > reactionsActionName | string | Optional |  | as above | A type of action you want to be added to your [Message](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message) object whenever a reaction is added to a published message, like `"reacted"`. The default message action used by Chat SDK is `"reactions"`. Expand the [Message-related types](https://www.pubnub.com/docs/chat/chat-sdk/learn/chat-entities/message#properties) section for more details. |
| cryptoModule | CryptoModule.aesCbcCryptoModule | Optional |  | Message and file encryption/decryption | Cryptography module used for encrypting and decrypting messages and files. It takes the `cipherKey` parameter as an argument. For more information and examples, refer to the [Data security](https://www.pubnub.com/docs/chat/chat-sdk/learn/access-control#data-security) section. |
| > cipherKey | string | Optional |  | as above | String used to automatically encrypt and decrypt all message and file data in your chat app. |
| syncMutedUsers | boolean | Optional | `false` | [User moderation](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/moderation-user) | Whether the mute list is synchronized across sessions and devices. For more information, refer to [Sync muted users](#sync-muted-users). |
| emitReadReceiptEvents | { | Optional | `{ direct: true, group: true, public: false, unknown: true }` | [Read receipts](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/read-receipts) | Controls which channel types automatically emit `receipt` events when messages are marked as read. When a channel type is `true`, the Chat SDK sends a `receipt` signal each time a user calls `setLastReadMessage()`, `setLastReadMessageTimetoken()`, or `markAllMessagesAsRead()`, enabling other channel members to receive updates via [onReadReceiptReceived()](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/read-receipts#get-read-receipts). |

#### Sync muted users

The `syncMutedUsers` parameter determines whether the [mute list](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/moderation-user) is synchronized across sessions and devices using a specific App Context User object.

When set to `false`, the mute list modifications are stored only for the duration of the current session. Once the session ends, the mute list is cleared.

When set to `true`, the client-side mute list is automatically saved and retrieved from App Context, ensuring that the muted user list persists beyond the current session. App Context uses a designated channel where all mute list data is sent: `PN_PRV.$currentUserId.mute1`.

:::warning Mute list and Access Manager
If you use [Access Manager](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/moderation) within your chat app and `syncMutedUsers` is enabled, you must grant the Chat SDK user the following permissions:
* `read` permission to the `PN_PRV.$currentUserId.mute1` channel.
* `update`, `delete`, and `get` permissions for the `PN_PRV.$currentUserId.mute1` user.
Make sure to change `$currentUserId` to the user ID of the chat user that will use the mute list functionality.
:::

#### Additional configuration options

Since the Chat SDK heavily relies on the latest [JavaScript SDK](https://www.pubnub.com/docs/sdks/javascript) for all the underlying methods, when initializing the Chat SDK client, you can also make use of all optional parameters that come with the JavaScript SDK.

For example, you may want to use [Access Manager](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/permissions) and initialize the Chat SDK with `secretKey` (in the server-side code) or `authKey` (in the client-side code). You can also decide how long the server will consider the client alive for presence (`presenceTimeout`) or how often the client will announce itself to the server (`heartbeatInterval`).

For the whole list of all such inherited optional parameters which you can define when initializing the Chat SDK instance, check the [JavaScript SDK configuration document](https://www.pubnub.com/docs/sdks/javascript/api-reference/configuration#methods).

### Output parameters

| Type | Description |
| --- | --- |
| `Promise<Chat>` | Object returning a new PubNub chat instance. |

### Sample code

#### Required setup

Use this basic example to include the PubNub Chat SDK package in your code and initialize the client setting only the required parameters.

```ts
// include the PubNub Chat SDK package in your code before initializing the client. Underneath, that also installs the PubNub JavaScript SDK "pubnub" package as a dependency.
import { Chat } from "@pubnub/chat"

// initialize your Chat SDK client using your app keys from the Admin Portal and a unique user ID for your client that you'll come up with
const chat = await Chat.init({
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
})
```

#### Typing indicator timeout

Initialize the PubNub Chat SDK and set the default typing indicator timeout value to `3000` milliseconds (three seconds).

```ts
import { Chat } from "@pubnub/chat"

const chat = Chat.init({
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId",
    typingTimeout: 3000
})
```

#### Client-side rate limiting

Initialize the PubNub Chat SDK and set the hard limit for message publishing on public channels to `3000` milliseconds (three seconds). If there are more publish retries within this limit, each next retry limit should be multiplied by `3`.

```ts
import { Chat } from "@pubnub/chat"

const chat = Chat.init({
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId",
    rateLimitPerChannel: {
      public: 1000
    },
    rateLimitFactor: 3
})
```

#### Initialize Chat SDK with Access Manager

Use a PubNub SDK instance [initialized with secretKey](https://www.pubnub.com/docs/general/security/access-control#server-side-operations) to [generate a token](https://www.pubnub.com/docs/chat/security) and return it to the client-side code. Then, initialize the PubNub Chat SDK and set the `authKey` to the token returned from the server-side code.

server-side code

```ts
const tokenReturnedFromServer = chatInstanceWithSecretKey.sdk.grantToken({
    ttl: 60, // This 'ttl' variable will still determine how long the token is valid (in minutes)
    resources: {
        uuids: {
            "user_alice": {
                get: true,
                update: true
            }
        },
        channels: {
            "chat_room_123": {
                read: true,
                write: true,
                get: true,
            }
        }
    }
});

// Pass the token to the client-side Chat instance initialization
```

client-side code

```ts
const chat = Chat.init({
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId",
    authKey: "tokenReturnedFromServer" // This is the token passed from the server-side code
})
```

#### Custom payload

When [initializing Chat SDK](https://www.pubnub.com/docs/chat/chat-sdk/build/configuration#initialize-pubnub), you can pass your custom message payload structure using the [customPayloads](#input-parameters) object and related properties. This will let Chat SDK correctly interpret your app's messages when sending and receiving them.

##### Define custom payload for all channels

Let's say your app doesn't follow the default `message.text` message body structure imposed by Chat SDK but instead uses the `my.custom.payload.structure.text` structure.

To successfully communicate with PubNub and send/receive messages through Chat SDK, pass your custom payload to all channels. Additionally, define your custom action names to be added to messages when they're edited or deleted.

```ts
import { Chat } from "@pubnub/chat"

const chat = Chat.init({
  publishKey: "demo",
  subscribeKey: "demo",
  userId: "myUniqueUserId",
  // If you don't define custom payload, messages on all channels will have the default "message.text" format
  customPayloads: {
    // Pass your custom message body structure so the Chat SDK can interpret your messages when sending them
    getMessagePublishBody: ({ type, text, files }) => {
      return {
        my: {
          custom: {
            payload: {
              structure: text,
            },
          },
        },
        // Optional parameter
        files,
        // Optional parameter
        messageType: type,
      };
    },
    // Pass the custom message body structure required by Chat SDK so it can interpret your messages when receiving them
    getMessageResponseBody: (messageParams: MessageDTOParams) => {
      return {
        // Required parameter for the default Chat SDK message body structure ("message.text")
        text: messageParams.message.my.custom.payload.structure,
        // Required parameter for the default Chat SDK message type structure ("text")
        type: messageParams.message.messageType,
        // Optional parameter for the default Chat SDK files structure (array of objects with properties "name", "id", "url", and an optional "type")
        files: messageParams.message.files,
      },
    },
    // Override the default Chat SDK action type for editing a message ("edited") with your own name
    editMessageActionName: "updated",
    // Override the default Chat SDK action type for deleting a message ("deleted") with your own name
    deleteMessageActionName: "removed",
  },
});
```

##### Define custom payload for one channel

Let's say your app doesn't follow the default `message.text` message body structure imposed by Chat SDK for `support-channel` but instead uses the `my.custom.payload.structure.text` structure to communicate with PubNub.

Pass your custom payload to `support-channel` to successfully communicate with PubNub and send/receive messages through Chat SDK. Additionally, define your custom action names to be added to messages when they're edited or deleted.

The code sets up a PubNub chat instance with specific handlers for processing message payloads differently based on the channel.

```ts
import { Chat } from "@pubnub/chat"

const chat = Chat.init({
  publishKey: "demo",
  subscribeKey: "demo",
  userId: "myUniqueUserId",
  // If you don't define custom payload, messages on all channels will have the default "message.text" format
  customPayloads: {
    // Pass your custom message body structure so the Chat SDK can interpret your messages when sending them on "support-channel"
    getMessagePublishBody: ({ type, text, files }, channelId) => {
      // Define which channel should use custom payload
      if (channelId === "support-channel") {
        return {
          my: {
            custom: {
              payload: {
                structure: text
              }
            }
          },
          // Optional parameter
          files,
          // Required parameter
          messageType: type,
        }
      }
      // The rest of the channels will use the default Chat SDK message body structure
      return {
        text,
        files,
        messageType: type,
      }
    },
    // Pass the custom message body structure required by Chat SDK so it can interpret your messages when receiving them on "support-channel"
    getMessageResponseBody: (messageParams: MessageDTOParams) => {
      if (messageParams.channel === "support-channel") {
        return {
          // Required parameter for your custom message body structure 
          text: messageParams.message.my.custom.payload.structure,
          // Required parameter for your custom message type structure (in this case, the default one is used)
          type: messageParams.message.messageType,
          // Optional parameter for your custom files structure (in this case, the default one is used)
          files: messageParams.message.files,
        }
      }

      return {
        // Required parameter for the default Chat SDK message body structure ("message.text")
        text: messageParams.message.text,
        // Required parameter for the default Chat SDK message type structure ("text")
        type: messageParams.message.messageType,
        // Optional parameter for the default Chat SDK files structure (array of objects with properties "name", "id", "url", and an optional "type")
        files: messageParams.message.files,
      }
    },
    // Override the default Chat SDK action type for editing a message ("edited") with your own name
    editMessageActionName: "updated",
    // Override the default Chat SDK action type for deleting a message ("deleted") with your own name
    deleteMessageActionName: "removed",
  },
});
```

## Destroy Chat instance

Use the `destroy()` method to release all resources held by the `Chat` instance and the underlying PubNub SDK instance. Call this when your app shuts down or when you no longer need the Chat SDK — for example, on user logout or component unmount.

### Method signature

```ts
chat.destroy()
```

### Input

None.

### Output

None. This is a fire-and-forget cleanup method.

### Sample code

```ts
import { Chat } from "@pubnub/chat"

const chat = await Chat.init({
    publishKey: "demo",
    subscribeKey: "demo",
    userId: "myUniqueUserId"
})

// Clean up resources when the app shuts down or the user logs out
chat.destroy()
```

## Next steps

After initialization, you can:

* Run the [sample chat app](https://www.pubnub.com/docs/chat/chat-sdk/build/sample-chat) to see a working example
* Create [channels](https://www.pubnub.com/docs/chat/chat-sdk/build/features/channels/create) and [users](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/create)
* Add features like [messaging](https://www.pubnub.com/docs/chat/chat-sdk/build/features/messages/send-receive), [typing indicators](https://www.pubnub.com/docs/chat/chat-sdk/build/features/channels/typing-indicator), and [presence](https://www.pubnub.com/docs/chat/chat-sdk/build/features/users/presence)

## Framework integration

The Chat SDK works with any TypeScript-compatible framework: React, React Native, Vue, Angular, and others.

**Requirements:**

* [yarn](https://classic.yarnpkg.com/en/docs/install) (>=1.22.19) or npm
* [Node.js](https://nodejs.org/en/download/package-manager/) (>=18.10.0)
* Code editor (for example, [Visual Studio Code](https://code.visualstudio.com/download))

### React

```tsx
// React imports
import { useEffect, useState } from "react";
// PubNub imports
// Give access to selected Chat SDK entities
import { Chat } from "@pubnub/chat";

// Initialize Chat SDK
export function SomeChatComponent() {
  const [chat, setChat] = useState<Chat>()

  useEffect(() => {
    // Define your PubNub API credentials and user ID here
    const publishKey = "put-your-publish-key-here";
    const subscribeKey = "put-your-subscribe-key-here";
    const userId = "put-your-user-id-here";

    Chat.init({
      publishKey,
      subscribeKey,
      userId,
      typingTimeout: 2000,
    }).then(setChat)
  }, []);

  // Add additional code to your app here

  return null;
}
```

### React Native

```tsx
// React imports
import { useEffect, useState } from "react";
// PubNub imports
// Give access to selected Chat SDK entities
import { Chat } from "@pubnub/chat";

// Initialize Chat SDK
export function SomeChatComponent() {
  const [chat, setChat] = useState<Chat>()

  useEffect(() => {
    // Define your PubNub API credentials and user ID here
    const publishKey = "put-your-publish-key-here";
    const subscribeKey = "put-your-subscribe-key-here";
    const userId = "put-your-user-id-here";

    Chat.init({
      publishKey,
      subscribeKey,
      userId,
      typingTimeout: 2000,
    }).then(setChat)
  }, []);

  // Add additional code to your app here

  return null;
}
```

### Vue

```tsx
// Vue imports
import { reactive } from "vue"
// PubNub imports
// Give access to selected Chat SDK entities
import { Chat } from "@pubnub/chat"

// Define your PubNub API credentials and user ID here
const publishKey = "put-your-publish-key-here"
const subscribeKey = "put-your-subscribe-key-here"
const userId = "put-your-user-id-here"

// Initialize Chat SDK
interface State {
  chat: Chat | null
}

const state: State = reactive({
  chat: null,
})

(async function () {
  state.chat = await Chat.init({
    publishKey,
    subscribeKey,
    userId,
    typingTimeout: 2000,
  })
})()

// Add additional code to your app here
```

### Angular

```tsx
// Angular imports
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
// PubNub imports
// Give access to selected Chat SDK entities
import { Chat } from "@pubnub/chat";

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
  // Define your PubNub API credentials and user ID here
  private publishKey = "put-your-publish-key-here";
  private subscribeKey = "put-your-subscribe-key-here";
  private userId = "put-your-user-id-here";

  private chat: Chat;

  constructor() {}

  // Initialize Chat SDK
  async ngOnInit() {
    this.chat = await Chat.init({
      publishKey: this.publishKey,
      subscribeKey: this.subscribeKey,
      userId: this.userId,
      typingTimeout: 2000,
    });

    // Add additional code to your app here
  }
}
```

For a complete example with channels, users, and messaging, see the [React Getting Started app](https://github.com/pubnub/js-chat/tree/master/samples/getting-started) and [guide](https://www.pubnub.com/docs/chat/chat-sdk/build/sample-chat).