Skip to main content
Follow these best practices to build reliable, performant, and secure applications with the CometChat JavaScript SDK.

Initialization & Authentication

PracticeDescription
Initialize once at startupCall CometChat.init() in your entry file (index.js, main.js, or App.js). It only needs to be called once per session.
Use environment variablesStore App ID, Region, and Auth Key in environment variables rather than hardcoding them.
Check for existing sessionsBefore calling login(), use CometChat.getLoggedinUser() to check if a session already exists.
Use Auth Tokens in productionAuth Keys are for development only. Generate Auth Tokens server-side using the REST API.
Handle token expiryImplement a mechanism to detect login failures due to expired tokens. Use the Login Listener to detect session changes.
Logout on sign-outAlways call CometChat.logout() when your user signs out to clear the SDK session and stop real-time events.

Listeners

PracticeDescription
Use unique listener IDsUse descriptive IDs like "MESSAGE_LISTENER_CHAT_SCREEN" to avoid accidental overwrites.
Register early, remove on cleanupRegister listeners after login(). Remove them when the component is destroyed to prevent memory leaks.
Keep callbacks lightweightAvoid heavy processing inside listener callbacks. Dispatch events to your state management layer.
Use specific listenersOnly register the listener types you need. Don’t register a GroupListener if your page only handles messages.

Pagination & Caching

PracticeDescription
Use reasonable limitsSet setLimit() to 30-50 for users, messages, and group members.
Reuse request objectsCall fetchNext()/fetchPrevious() on the same request instance. Creating a new object resets the cursor.
Cache frequently accessed dataStore user and group objects locally to reduce API calls.

Rate Limits

PracticeDescription
Batch operationsSpace out bulk operations using a queue or throttle mechanism.
Monitor rate limit headersCheck X-Rate-Limit-Remaining in REST API responses to slow down before hitting limits.
Distinguish operation typesCore operations (login, create/delete user) share a 10,000/min limit. Standard operations have 20,000/min. Avoid frequent login/logout cycles.

SSR Frameworks

PracticeDescription
Initialize client-side onlyCometChat requires browser APIs. Use dynamic imports or useEffect for Next.js, Nuxt, etc.
Use loading statesShow a loading indicator while the SDK initializes to prevent hydration mismatches.

Messaging

PracticeDescription
Use appropriate message typesChoose text, media, or custom messages based on your content.
Add metadata for contextUse setMetadata() to attach location, device info, or other contextual data.
Handle errors gracefullyAlways implement error callbacks to handle network issues or invalid parameters.
Validate file typesBefore sending media messages, verify the file type matches the message type.
Hide deleted/blocked contentUse hideDeletedMessages(true) and hideMessagesFromBlockedUsers(true) for cleaner lists.

Threaded Messages

PracticeDescription
Track active thread IDStore the current thread’s parentMessageId to filter incoming messages.
Use hideReplies(true)Exclude thread replies from main conversation to avoid clutter.
Show reply countDisplay the number of replies on parent messages to indicate thread activity.

Reactions & Mentions

PracticeDescription
Update UI optimisticallyShow reactions immediately, then sync with server response.
Use correct mention formatAlways use <@uid:UID> format for mentions in message text.
Highlight mentions in UIParse message text and style mentions differently.

Typing Indicators

PracticeDescription
Debounce typing eventsDon’t call startTyping() on every keystroke - debounce to ~300ms intervals.
Auto-stop typingCall endTyping() after 3-5 seconds of inactivity or when the user sends a message.

Delivery & Read Receipts

PracticeDescription
Mark as delivered on fetchCall markAsDelivered() when messages are fetched and displayed.
Mark as read on viewCall markAsRead() when the user actually views/scrolls to a message.
Batch receiptsMark the last message in a batch - all previous messages are automatically marked.

Groups

PracticeDescription
Use meaningful GUIDsChoose descriptive, unique GUIDs (e.g., "project-alpha-team").
Set group type carefullyGroup type cannot be changed after creation. Choose between PUBLIC, PASSWORD, and PRIVATE.
Add members at creationUse createGroupWithMembers() to add initial members in a single API call.
Check hasJoined before joiningAvoid unnecessary API calls by checking the group’s hasJoined property first.
Transfer ownership before leavingOwners 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

PracticeDescription
Batch member additionsAdd multiple members in a single addMembersToGroup() call.
Set appropriate scopesAssign PARTICIPANT by default. Only use ADMIN or MODERATOR when needed.
Handle partial failuresCheck each entry in the response array for "success" or an error message.
Use scope constantsUse CometChat.GROUP_MEMBER_SCOPE.ADMIN instead of raw strings.
Kick vs. BanUse kick when the user can rejoin. Use ban for permanent removal until unbanned.

Calling

PracticeDescription
Initialize Calls SDK after Chat SDKAlways initialize Chat SDK (CometChat.init()) before Calls SDK (CometChatCalls.init()).
Store session ID immediatelySave the session ID from initiateCall() response - you’ll need it for accept, reject, cancel.
Handle all call statesImplement handlers for all listener events (accepted, rejected, cancelled, busy, ended).
Generate tokens just-in-timeGenerate call tokens immediately before starting a session rather than caching them.
Clean up on session endAlways call CometChatCalls.endSession() in both onCallEnded and onCallEndButtonPressed callbacks.
Inform users about recordingAlways notify participants when recording starts - this is often a legal requirement.
Limit presenters to 5Additional users should join as viewers.

Custom CSS (Calling)

PracticeDescription
Only use documented CSS classesUndocumented internal classes may break with SDK updates.
Don’t resize the grid containerOnly customize colors, borders, and visibility.
Test across modesCSS changes may look different in DEFAULT, TILE, and SPOTLIGHT modes.
Keep button sizes accessibleMinimum 44x44px for touch targets.

Connection & WebSocket

PracticeDescription
Register connection listener earlyAdd the listener right after CometChat.init() succeeds.
Show connection status in UIDisplay a banner when disconnected so users know messages may be delayed.
Queue actions during disconnectionQueue user actions and retry once onConnected fires.
Don’t poll getConnectionStatus()Use the listener-based approach instead.
Reconnect on app foregroundIf you disconnect in background, call CometChat.connect() when returning to foreground.

AI Features

PracticeDescription
Register both listeners for AI AgentsUse AIAssistantListener for streaming events and MessageListener for persisted messages.
Handle streaming progressivelyRender the assistant’s reply token-by-token using Text Message Content events.
Show pending state for moderationDisplay a visual indicator when getModerationStatus() returns PENDING.
Handle disapproved messages gracefullyShow a placeholder or notification so the sender understands what happened.
Track pending messagesMaintain a local map of pending message IDs to update UI when moderation results arrive.

Upgrading from V3

PracticeDescription
Follow the setup guide firstComplete the v4 setup instructions before changing imports.
Update all imports at onceUse find-and-replace to change all @cometchat-pro/chat imports to @cometchat/chat-sdk-javascript.
Test incrementallyTest each feature area (messaging, calling, groups) individually after updating.
Remove old packagesUninstall v3 packages (npm uninstall @cometchat-pro/chat) to avoid conflicts.

Next Steps

Troubleshooting

Common issues and solutions

Setup SDK

Installation and initialization guide