> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-rn-guide-message-privately.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Best Practices

> Build reliable CometChat JavaScript SDK apps with secure auth, listener cleanup, pagination, caching, error handling, and performance practices.

Follow these best practices to build reliable, performant, and secure applications with the CometChat JavaScript SDK. Organized by topic — jump to what's relevant for your current work.

## Initialization & Authentication

| Practice                      | Description                                                                                                                                                                       |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Initialize once at startup    | Call `CometChat.init()` in your entry file (`index.js`, `main.js`, or `App.js`). It only needs to be called once per session.                                                     |
| Use environment variables     | Store App ID, Region, and Auth Key in environment variables rather than hardcoding them.                                                                                          |
| Check for existing sessions   | Before calling `login()`, use `CometChat.getLoggedinUser()` to check if a session already exists.                                                                                 |
| Use Auth Tokens in production | Auth Keys are for development only. Generate Auth Tokens server-side using the [REST API](https://api-explorer.cometchat.com/reference/create-authtoken).                         |
| Handle token expiry           | Implement a mechanism to detect login failures due to expired tokens. Use the [Login Listener](/sdk/javascript/authentication-overview#login-listener) to detect session changes. |
| Logout on sign-out            | Always call `CometChat.logout()` when your user signs out to clear the SDK session and stop real-time events.                                                                     |

## Listeners

| Practice                          | Description                                                                                                     |
| --------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Use unique listener IDs           | Use descriptive IDs like `"MESSAGE_LISTENER_CHAT_SCREEN"` to avoid accidental overwrites.                       |
| Register early, remove on cleanup | Register listeners after `login()`. Remove them when the component is destroyed to prevent memory leaks.        |
| Keep callbacks lightweight        | Avoid heavy processing inside listener callbacks. Dispatch events to your state management layer.               |
| Use specific listeners            | Only register the listener types you need. Don't register a `GroupListener` if your page only handles messages. |

## Pagination & Caching

| Practice                       | Description                                                                                                 |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Use reasonable limits          | Set `setLimit()` to 30-50 for users, messages, and group members.                                           |
| Reuse request objects          | Call `fetchNext()`/`fetchPrevious()` on the same request instance. Creating a new object resets the cursor. |
| Cache frequently accessed data | Store user and group objects locally to reduce API calls.                                                   |

## Rate Limits

| Practice                    | Description                                                                                                                                    |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Batch operations            | Space out bulk operations using a queue or throttle mechanism.                                                                                 |
| Monitor rate limit headers  | Check `X-Rate-Limit-Remaining` in REST API responses to slow down before hitting limits.                                                       |
| Distinguish operation types | Core operations (login, create/delete user) share a 10,000/min limit. Standard operations have 20,000/min. Avoid frequent login/logout cycles. |

## SSR Frameworks

| Practice                    | Description                                                                                 |
| --------------------------- | ------------------------------------------------------------------------------------------- |
| Initialize client-side only | CometChat requires browser APIs. Use dynamic imports or `useEffect` for Next.js, Nuxt, etc. |
| Use loading states          | Show a loading indicator while the SDK initializes to prevent hydration mismatches.         |

## Messaging

| Practice                      | Description                                                                                 |
| ----------------------------- | ------------------------------------------------------------------------------------------- |
| Use appropriate message types | Choose text, media, or custom messages based on your content.                               |
| Add metadata for context      | Use `setMetadata()` to attach location, device info, or other contextual data.              |
| Handle errors gracefully      | Always implement error callbacks to handle network issues or invalid parameters.            |
| Validate file types           | Before sending media messages, verify the file type matches the message type.               |
| Hide deleted/blocked content  | Use `hideDeletedMessages(true)` and `hideMessagesFromBlockedUsers(true)` for cleaner lists. |

## Threaded Messages

| Practice               | Description                                                                   |
| ---------------------- | ----------------------------------------------------------------------------- |
| Track active thread ID | Store the current thread's `parentMessageId` to filter incoming messages.     |
| Use hideReplies(true)  | Exclude thread replies from main conversation to avoid clutter.               |
| Show reply count       | Display the number of replies on parent messages to indicate thread activity. |

## Reactions & Mentions

| Practice                   | Description                                                  |
| -------------------------- | ------------------------------------------------------------ |
| Update UI optimistically   | Show reactions immediately, then sync with server response.  |
| Use correct mention format | Always use `<@uid:UID>` format for mentions in message text. |
| Highlight mentions in UI   | Parse message text and style mentions differently.           |

## Typing Indicators

| Practice               | Description                                                                          |
| ---------------------- | ------------------------------------------------------------------------------------ |
| Debounce typing events | Don't call `startTyping()` on every keystroke - debounce to \~300ms intervals.       |
| Auto-stop typing       | Call `endTyping()` after 3-5 seconds of inactivity or when the user sends a message. |

## Delivery & Read Receipts

| Practice                   | Description                                                                        |
| -------------------------- | ---------------------------------------------------------------------------------- |
| Mark as delivered on fetch | Call `markAsDelivered()` when messages are fetched and displayed.                  |
| Mark as read on view       | Call `markAsRead()` when the user actually views/scrolls to a message.             |
| Batch receipts             | Mark the last message in a batch - all previous messages are automatically marked. |

## Groups

| Practice                          | Description                                                                                |
| --------------------------------- | ------------------------------------------------------------------------------------------ |
| Use meaningful GUIDs              | Choose descriptive, unique GUIDs (e.g., `"project-alpha-team"`).                           |
| Set group type carefully          | Group type cannot be changed after creation. Choose between PUBLIC, PASSWORD, and PRIVATE. |
| Add members at creation           | Use `createGroupWithMembers()` to add initial members in a single API call.                |
| Check hasJoined before joining    | Avoid unnecessary API calls by checking the group's `hasJoined` property first.            |
| Transfer ownership before leaving | Owners must transfer ownership to another member before they can leave.                    |
| Use joinedOnly(true)              | Filter to joined groups when building sidebars or group lists.                             |

## Group Members

| Practice                | Description                                                                      |
| ----------------------- | -------------------------------------------------------------------------------- |
| Batch member additions  | Add multiple members in a single `addMembersToGroup()` call.                     |
| Set appropriate scopes  | Assign `PARTICIPANT` by default. Only use `ADMIN` or `MODERATOR` when needed.    |
| Handle partial failures | Check each entry in the response array for `"success"` or an error message.      |
| Use scope constants     | Use `CometChat.GROUP_MEMBER_SCOPE.ADMIN` instead of raw strings.                 |
| Kick vs. Ban            | Use kick when the user can rejoin. Use ban for permanent removal until unbanned. |

## Calling

| Practice                            | Description                                                                                             |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Initialize Calls SDK after Chat SDK | Always initialize Chat SDK (`CometChat.init()`) before Calls SDK (`CometChatCalls.init()`).             |
| Store session ID immediately        | Save the session ID from `initiateCall()` response - you'll need it for accept, reject, cancel.         |
| Handle all call states              | Implement handlers for all listener events (accepted, rejected, cancelled, busy, ended).                |
| Generate tokens just-in-time        | Generate call tokens immediately before starting a session rather than caching them.                    |
| Clean up on session end             | Always call `CometChatCalls.endSession()` in both `onCallEnded` and `onCallEndButtonPressed` callbacks. |
| Inform users about recording        | Always notify participants when recording starts - this is often a legal requirement.                   |

## Custom CSS (Calling)

| Practice                        | Description                                                                 |
| ------------------------------- | --------------------------------------------------------------------------- |
| Only use documented CSS classes | Undocumented internal classes may break with SDK updates.                   |
| Don't resize the grid container | Only customize colors, borders, and visibility.                             |
| Test across modes               | CSS changes may look different in `DEFAULT`, `TILE`, and `SPOTLIGHT` modes. |
| Keep button sizes accessible    | Minimum 44x44px for touch targets.                                          |

## Connection & WebSocket

| Practice                           | Description                                                                               |
| ---------------------------------- | ----------------------------------------------------------------------------------------- |
| Register connection listener early | Add the listener right after `CometChat.init()` succeeds.                                 |
| Show connection status in UI       | Display a banner when disconnected so users know messages may be delayed.                 |
| Queue actions during disconnection | Queue user actions and retry once `onConnected` fires.                                    |
| Don't poll getConnectionStatus()   | Use the listener-based approach instead.                                                  |
| Reconnect on app foreground        | If you disconnect in background, call `CometChat.connect()` when returning to foreground. |

## AI Features

| Practice                               | Description                                                                                  |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| Register both listeners for AI Agents  | Use `AIAssistantListener` for streaming events and `MessageListener` for persisted messages. |
| Handle streaming progressively         | Render the assistant's reply token-by-token using `Text Message Content` events.             |
| Show pending state for moderation      | Display a visual indicator when `getModerationStatus()` returns `PENDING`.                   |
| Handle disapproved messages gracefully | Show a placeholder or notification so the sender understands what happened.                  |
| Track pending messages                 | Maintain a local map of pending message IDs to update UI when moderation results arrive.     |

## Upgrading from V3

| Practice                     | Description                                                                                           |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| Follow the setup guide first | Complete the v4 [setup instructions](/sdk/javascript/setup-sdk) before changing imports.              |
| Update all imports at once   | Use find-and-replace to change all `@cometchat-pro/chat` imports to `@cometchat/chat-sdk-javascript`. |
| Test incrementally           | Test each feature area (messaging, calling, groups) individually after updating.                      |
| Remove old packages          | Uninstall v3 packages (`npm uninstall @cometchat-pro/chat`) to avoid conflicts.                       |

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Troubleshooting" icon="wrench" href="/sdk/javascript/troubleshooting">
    Common issues and solutions
  </Card>

  <Card title="Error Codes" icon="triangle-exclamation" href="/sdk/javascript/error-codes">
    Complete SDK error code reference
  </Card>

  <Card title="Rate Limits" icon="gauge-high" href="/sdk/javascript/rate-limits">
    Understand and handle API rate limits
  </Card>

  <Card title="Setup SDK" icon="gear" href="/sdk/javascript/setup-sdk">
    Installation and initialization guide
  </Card>
</CardGroup>
