Skip to main content
{
  "component": "CometChatUsers",
  "package": "@cometchat/chat-uikit-react-native",
  "import": "import { CometChatUsers } from \"@cometchat/chat-uikit-react-native\";",
  "description": "Searchable, scrollable list of all available users with avatar, name, and online/offline status.",
  "primaryOutput": {
    "prop": "onItemPress",
    "type": "(user: CometChat.User) => void"
  },
  "props": {
    "data": {
      "usersRequestBuilder": {
        "type": "CometChat.UsersRequestBuilder",
        "default": "SDK default (30 per page)",
        "note": "Pass the builder, not the result of .build()"
      },
      "searchRequestBuilder": {
        "type": "CometChat.UsersRequestBuilder",
        "default": "undefined"
      },
      "searchKeyword": {
        "type": "string",
        "default": "\"\""
      }
    },
    "callbacks": {
      "onItemPress": "(user: CometChat.User) => void",
      "onItemLongPress": "(user: CometChat.User) => void",
      "onBack": "() => void",
      "onSelection": "(list: CometChat.User[]) => void",
      "onError": "(error: CometChat.CometChatException) => void",
      "onEmpty": "() => void",
      "onLoad": "(list: CometChat.User[]) => void",
      "onSubmit": "(list: Array<CometChat.User>) => void"
    },
    "visibility": {
      "hideHeader": { "type": "boolean", "default": false },
      "showBackButton": { "type": "boolean", "default": false },
      "hideSearch": { "type": "boolean", "default": false },
      "hideError": { "type": "boolean", "default": false },
      "stickyHeaderVisibility": { "type": "boolean", "default": true },
      "hideSubmitButton": { "type": "boolean", "default": true },
      "hideLoadingState": { "type": "boolean", "default": false },
      "usersStatusVisibility": { "type": "boolean", "default": true },
      "title": { "type": "string", "default": "\"Users\"" }
    },
    "selection": {
      "selectionMode": {
        "type": "SelectionMode",
        "values": ["single", "multiple", "none"],
        "default": "none"
      }
    },
    "viewSlots": {
      "ItemView": "(user: CometChat.User) => JSX.Element",
      "LeadingView": "(user: CometChat.User) => JSX.Element",
      "TitleView": "(user: CometChat.User) => JSX.Element",
      "SubtitleView": "(user: CometChat.User) => JSX.Element",
      "TrailingView": "(user: CometChat.User) => JSX.Element",
      "LoadingView": "() => JSX.Element",
      "EmptyView": "() => JSX.Element",
      "ErrorView": "() => JSX.Element",
      "AppBarOptions": "() => JSX.Element"
    },
    "menu": {
      "options": "(user: CometChat.User) => MenuItemInterface[]",
      "addOptions": "(user: CometChat.User) => MenuItemInterface[]"
    },
    "search": {
      "searchPlaceholderText": { "type": "string", "default": "\"Search\"" }
    }
  },
  "events": [
    {
      "name": "ccUserBlocked",
      "payload": "CometChat.User",
      "description": "Triggered when logged-in user blocks another user"
    },
    {
      "name": "ccUserUnblocked",
      "payload": "CometChat.User",
      "description": "Triggered when logged-in user unblocks another user"
    }
  ],
  "sdkListeners": [
    "onUserOnline",
    "onUserOffline"
  ],
  "compositionExample": {
    "description": "User list wired to message view",
    "components": [
      "CometChatUsers",
      "CometChatMessageHeader",
      "CometChatMessageList",
      "CometChatMessageComposer"
    ],
    "flow": "onItemPress emits CometChat.User -> pass to MessageHeader, MessageList, MessageComposer"
  },
  "types": {
    "SelectionMode": {
      "single": "Select one user at a time",
      "multiple": "Select multiple users",
      "none": "No selection mode"
    }
  }
}

Where It Fits

CometChatUsers is a contact list component. It renders all available users and emits the selected CometChat.User via onItemPress. Wire it to CometChatMessageHeader, CometChatMessageList, and CometChatMessageComposer to build a standard two-panel chat layout.
import { useState } from "react";
import { View, Text, StyleSheet } from "react-native";
import { GestureHandlerRootView } from "react-native-gesture-handler";
import { SafeAreaProvider } from "react-native-safe-area-context";
import {
  CometChatUsers,
  CometChatMessageHeader,
  CometChatMessageList,
  CometChatMessageComposer,
  CometChatThemeProvider,
} from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function ChatApp() {
  const [selectedUser, setSelectedUser] = useState<CometChat.User>();

  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <SafeAreaProvider>
        <CometChatThemeProvider>
          <View style={styles.container}>
            <View style={styles.sidebar}>
              <CometChatUsers onItemPress={(user) => setSelectedUser(user)} />
            </View>
            {selectedUser ? (
              <View style={styles.chatArea}>
                <CometChatMessageHeader user={selectedUser} />
                <CometChatMessageList user={selectedUser} />
                <CometChatMessageComposer user={selectedUser} />
              </View>
            ) : (
              <View style={styles.placeholder}>
                <Text>Select a user</Text>
              </View>
            )}
          </View>
        </CometChatThemeProvider>
      </SafeAreaProvider>
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: { flex: 1, flexDirection: "row" },
  sidebar: { width: 350 },
  chatArea: { flex: 1 },
  placeholder: { flex: 1, justifyContent: "center", alignItems: "center" },
});

Minimal Render

import { CometChatUsers } from "@cometchat/chat-uikit-react-native";

function UsersDemo() {
  return <CometChatUsers />;
}

export default UsersDemo;

Filtering Users

Pass a CometChat.UsersRequestBuilder to usersRequestBuilder. Pass the builder instance — not the result of .build().
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function FilteredUsers() {
  return (
    <CometChatUsers
      usersRequestBuilder={
        new CometChat.UsersRequestBuilder().friendsOnly(true).setLimit(15)
      }
    />
  );
}

Filter Recipes

RecipeCode
Friends onlynew CometChat.UsersRequestBuilder().friendsOnly(true)
Online users onlynew CometChat.UsersRequestBuilder().setStatus("online")
Limit to 15 per pagenew CometChat.UsersRequestBuilder().setLimit(15)
Search by keywordnew CometChat.UsersRequestBuilder().setSearchKeyword("alice")
Hide blocked usersnew CometChat.UsersRequestBuilder().hideBlockedUsers(true)
Filter by rolesnew CometChat.UsersRequestBuilder().setRoles(["admin", "moderator"])
Filter by tagsnew CometChat.UsersRequestBuilder().setTags(["vip"])
Specific UIDsnew CometChat.UsersRequestBuilder().setUIDs(["uid1", "uid2"])
Default page size is 30. The component uses infinite scroll — the next page loads as the user scrolls to the bottom. A separate searchRequestBuilder can be passed to filter the search list independently from the main list. Refer to UsersRequestBuilder for the full builder API.

Actions and Events

Callback Props

onItemPress

Fires when a user row is tapped. Primary navigation hook — set the active user and render the message view.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function UsersWithPress() {
  const handleItemPress = (user: CometChat.User) => {
    console.log("Selected:", user.getName());
  };

  return <CometChatUsers onItemPress={handleItemPress} />;
}

onItemLongPress

Fires when a user item is long-pressed, allowing additional actions like block or report.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function UsersWithLongPress() {
  const handleLongPress = (user: CometChat.User) => {
    console.log("Long pressed:", user.getName());
  };

  return <CometChatUsers onItemLongPress={handleLongPress} />;
}

onSelection

Fires when users are selected/deselected in selection mode. Requires selectionMode to be set.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function UsersWithSelection() {
  const handleSelection = (list: CometChat.User[]) => {
    console.log("Selected:", list.length);
  };

  return (
    <CometChatUsers
      selectionMode="multiple"
      onSelection={handleSelection}
    />
  );
}

onEmpty

Fires when the user list fetch returns zero results.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";

function UsersWithEmptyHandler() {
  return (
    <CometChatUsers onEmpty={() => console.log("No users available")} />
  );
}

onError

Fires on internal errors (network failure, auth issue, SDK exception).
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function UsersWithErrorHandler() {
  return (
    <CometChatUsers
      onError={(error: CometChat.CometChatException) => {
        console.error("CometChatUsers error:", error);
      }}
    />
  );
}

onLoad

Fires when the list is successfully fetched and loaded.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function UsersWithLoadHandler() {
  const handleLoad = (list: CometChat.User[]) => {
    console.log("Users loaded:", list.length);
  };

  return <CometChatUsers onLoad={handleLoad} />;
}

Global UI Events

CometChatUIEventHandler emits events subscribable from anywhere in the application. Subscribe in a useEffect and unsubscribe on cleanup.
EventFires whenPayload
ccUserBlockedThe logged-in user blocks another userCometChat.User
ccUserUnblockedThe logged-in user unblocks another userCometChat.User
import { useEffect } from "react";
import { CometChatUIEventHandler } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function useUserEvents() {
  useEffect(() => {
    const listenerId = "USER_EVENTS_" + Date.now();
    
    CometChatUIEventHandler.addUserListener(listenerId, {
      ccUserBlocked: (user: CometChat.User) => {
        console.log("Blocked:", user.getName());
      },
      ccUserUnblocked: (user: CometChat.User) => {
        console.log("Unblocked:", user.getName());
      },
    });

    return () => {
      CometChatUIEventHandler.removeUserListener(listenerId);
    };
  }, []);
}

SDK Events (Real-Time, Automatic)

The component listens to these SDK events internally. No manual attachment needed unless additional side effects are required.
SDK ListenerInternal behavior
onUserOnlineUpdates the user’s status dot to online
onUserOfflineUpdates the user’s status dot to offline

Custom View Slots

Each slot replaces a section of the default UI. Slots that accept a user parameter receive the CometChat.User object for that row.
SlotSignatureReplaces
ItemView(user: CometChat.User) => JSX.ElementEntire list item row
LeadingView(user: CometChat.User) => JSX.ElementAvatar / left section
TitleView(user: CometChat.User) => JSX.ElementName / title text
SubtitleView(user: CometChat.User) => JSX.ElementSubtitle text
TrailingView(user: CometChat.User) => JSX.ElementRight section
LoadingView() => JSX.ElementLoading spinner
EmptyView() => JSX.ElementEmpty state
ErrorView() => JSX.ElementError state
AppBarOptions() => JSX.ElementHeader bar options

ItemView

Replace the entire list item row.
import {
  CometChatUsers,
  CometChatAvatar,
  useTheme,
} from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";
import { View, Text } from "react-native";

function CustomItemViewUsers() {
  const theme = useTheme();

  const getItemView = (user: CometChat.User) => {
    return (
      <View
        style={{
          flexDirection: "row",
          flex: 1,
          paddingHorizontal: 16,
          paddingVertical: 12,
          alignItems: "center",
          borderWidth: 1,
          borderColor: theme.color.borderLight,
        }}>
        <CometChatAvatar
          name={user.getName()}
          image={{ uri: user.getAvatar() }}
          style={{
            containerStyle: { borderRadius: 8 },
            imageStyle: { borderRadius: 8 },
          }}
        />
        <Text
          style={{
            flex: 1,
            color: theme.color.textPrimary,
            fontSize: 16,
            marginLeft: 12,
            fontWeight: "500",
          }}
          numberOfLines={1}
          ellipsizeMode="tail">
          {user.getName()}
        </Text>
      </View>
    );
  };

  return <CometChatUsers ItemView={getItemView} />;
}

LeadingView

Replace the avatar / left section.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";
import { View, Text } from "react-native";

function LeadingViewUsers() {
  const getLeadingView = (user: CometChat.User) => {
    return (
      <View
        style={{
          width: 40,
          height: 40,
          borderRadius: 20,
          backgroundColor: "#6852D6",
          justifyContent: "center",
          alignItems: "center",
        }}>
        <Text style={{ color: "white", fontWeight: "bold" }}>
          {user.getName().charAt(0)}
        </Text>
      </View>
    );
  };

  return <CometChatUsers LeadingView={getLeadingView} />;
}

SubtitleView

Replace the subtitle text.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";
import { Text } from "react-native";

function SubtitleViewUsers() {
  const getSubtitleView = (user: CometChat.User) => {
    return (
      <Text style={{ fontSize: 12, color: "#727272" }}>
        {user.getStatus() === "online" ? "Online" : "Offline"}
      </Text>
    );
  };

  return <CometChatUsers SubtitleView={getSubtitleView} />;
}

TrailingView

Replace the right section.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";
import { TouchableOpacity, Text } from "react-native";

function TrailingViewUsers() {
  const getTrailingView = (user: CometChat.User) => {
    return (
      <TouchableOpacity onPress={() => console.log("Follow:", user.getName())}>
        <Text style={{ color: "#6852D6", fontWeight: "500" }}>Follow</Text>
      </TouchableOpacity>
    );
  };

  return <CometChatUsers TrailingView={getTrailingView} />;
}

AppBarOptions

Custom view for the header bar options.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { TouchableOpacity, Text } from "react-native";

function AppBarOptionsUsers() {
  return (
    <CometChatUsers
      AppBarOptions={() => (
        <TouchableOpacity onPress={() => console.log("Settings pressed")}>
          <Text style={{ color: "#6852D6", fontWeight: "500" }}>Settings</Text>
        </TouchableOpacity>
      )}
    />
  );
}

options

Custom context menu actions for each user item.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function OptionsUsers() {
  const getOptions = (user: CometChat.User) => [
    {
      text: "Block",
      onPress: () => console.log("Block:", user.getName()),
    },
    {
      text: "Report",
      onPress: () => console.log("Report:", user.getName()),
    },
  ];

  return <CometChatUsers options={getOptions} />;
}

Common Patterns

Custom empty state with CTA

import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { View, Text, TouchableOpacity } from "react-native";

function EmptyStateUsers() {
  return (
    <CometChatUsers
      EmptyView={() => (
        <View style={{ flex: 1, justifyContent: "center", alignItems: "center", padding: 40 }}>
          <Text style={{ fontSize: 16, marginBottom: 16 }}>No users found</Text>
          <TouchableOpacity
            style={{ backgroundColor: "#6852D6", paddingHorizontal: 20, paddingVertical: 10, borderRadius: 8 }}
            onPress={() => console.log("Invite users")}>
            <Text style={{ color: "white" }}>Invite users</Text>
          </TouchableOpacity>
        </View>
      )}
    />
  );
}

Friends-only list

import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function FriendsOnlyUsers() {
  return (
    <CometChatUsers
      usersRequestBuilder={
        new CometChat.UsersRequestBuilder().friendsOnly(true).setLimit(15)
      }
    />
  );
}

Multi-select with submit

import { CometChatUsers } from "@cometchat/chat-uikit-react-native";
import { CometChat } from "@cometchat/chat-sdk-react-native";

function MultiSelectUsers() {
  const handleSubmit = (users: Array<CometChat.User>) => {
    console.log("Selected users:", users.length);
  };

  return (
    <CometChatUsers
      selectionMode="multiple"
      hideSubmitButton={false}
      onSubmit={handleSubmit}
    />
  );
}

Hide all chrome — minimal list

import { CometChatUsers } from "@cometchat/chat-uikit-react-native";

function MinimalUsers() {
  return (
    <CometChatUsers
      hideSearch={true}
      usersStatusVisibility={false}
      stickyHeaderVisibility={false}
      hideHeader={true}
    />
  );
}

Styling

The component uses the theme system from CometChatThemeProvider. Pass a style prop to customize the appearance.
import { CometChatUsers } from "@cometchat/chat-uikit-react-native";

function StyledUsers() {
  return (
    <CometChatUsers
      style={{
        titleStyle: {
          color: "#FBAA75",
        },
        titleSeparatorStyle: {
          borderBottomColor: "#FBAA75",
        },
        itemStyle: {
          avatarStyle: {
            containerStyle: {
              borderRadius: 8,
              backgroundColor: "#FBAA75",
            },
            imageStyle: {
              borderRadius: 8,
            },
          },
        },
      }}
    />
  );
}

Style Properties

PropertyTypeDescription
containerStyleViewStyleStyle for the root container
headerStyleViewStyleStyle for the header section
titleStyleTextStyleStyle for the header title
titleSeparatorStyleViewStyleStyle for section header separators
itemStyleobjectStyle for list items (includes avatarStyle, titleStyle, subtitleStyle)
searchStyleobjectStyle for the search bar

Props

All props are optional unless noted.

EmptyView

Custom component displayed when there are no users.
Type() => JSX.Element
DefaultBuilt-in empty state

ErrorView

Custom component displayed when an error occurs.
Type() => JSX.Element
DefaultBuilt-in error state

hideError

Hides the error state view.
Typeboolean
Defaultfalse

hideHeader

Hides the entire header bar.
Typeboolean
Defaultfalse

hideLoadingState

Hides the loading state while fetching users.
Typeboolean
Defaultfalse

hideSearch

Hides the search bar.
Typeboolean
Defaultfalse

hideSubmitButton

Hides the submit button when selection mode is enabled.
Typeboolean
Defaulttrue

ItemView

Custom renderer for the entire list item row.
Type(user: CometChat.User) => JSX.Element
DefaultBuilt-in list item

LeadingView

Custom renderer for the avatar / left section.
Type(user: CometChat.User) => JSX.Element
DefaultBuilt-in avatar

LoadingView

Custom component displayed during the loading state.
Type() => JSX.Element
DefaultBuilt-in loading indicator

onBack

Callback fired when the back button is pressed.
Type() => void
Defaultundefined

onEmpty

Callback fired when the user list is empty.
Type() => void
Defaultundefined

onError

Callback fired when the component encounters an error.
Type(error: CometChat.CometChatException) => void
Defaultundefined

onItemLongPress

Callback fired when a user row is long-pressed.
Type(user: CometChat.User) => void
Defaultundefined

onItemPress

Callback fired when a user row is tapped.
Type(user: CometChat.User) => void
Defaultundefined

onLoad

Callback fired when users are loaded.
Type(list: CometChat.User[]) => void
Defaultundefined

onSelection

Callback fired when users are selected/deselected. Requires selectionMode to be set.
Type(list: CometChat.User[]) => void
Defaultundefined

onSubmit

Callback fired when the submit button is pressed. Requires selectionMode to be set.
Type(list: Array<CometChat.User>) => void
Defaultundefined

searchKeyword

Pre-fills the search and filters the user list.
Typestring
Default""

searchRequestBuilder

Request builder with search parameters to fetch users.
TypeCometChat.UsersRequestBuilder
Defaultundefined

selectionMode

Enables single or multi-select mode on list items.
Type"single" | "multiple" | "none"
Default"none"

showBackButton

Shows the back button in the header.
Typeboolean
Defaultfalse

stickyHeaderVisibility

Shows/hides alphabetical section headers (A, B, C…).
Typeboolean
Defaulttrue

SubtitleView

Custom renderer for the subtitle text.
Type(user: CometChat.User) => JSX.Element
Defaultundefined

TitleView

Custom renderer for the name / title text.
Type(user: CometChat.User) => JSX.Element
DefaultBuilt-in title

TrailingView

Custom renderer for the right section.
Type(user: CometChat.User) => JSX.Element
DefaultBuilt-in trailing view

usersRequestBuilder

Controls which users load and in what order.
TypeCometChat.UsersRequestBuilder
DefaultSDK default (30 per page)
Pass the builder instance, not the result of .build().

usersStatusVisibility

Shows/hides the online/offline status indicator.
Typeboolean
Defaulttrue

title

Custom title for the header.
Typestring
Default"Users"

AppBarOptions

Custom component for the header bar options.
Type() => JSX.Element
Defaultundefined

addOptions

Function to append additional menu items to the default context menu.
Type(user: CometChat.User) => MenuItemInterface[]
Defaultundefined

options

Function to replace the default context menu items entirely.
Type(user: CometChat.User) => MenuItemInterface[]
Defaultundefined

searchPlaceholderText

Placeholder text for the search input.
Typestring
Default"Search"

Next Steps