> ## Documentation Index
> Fetch the complete documentation index at: https://docs.collab-kit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Users

> Track active editors and page through all users in a room.

The Users module exposes two user maps with different guarantees:

* `users.active` is the complete realtime set of active editors in the room, excluding the current user.
* `users.all` is a local cache populated only by explicit `users.list(...)` calls, excluding the current user.

Access the collection via `client.users`, or use `client.currentUser` for the local user.

## Collections

| Property | Type                         | Description                                                                                                          |
| -------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `active` | `Map<string, CollabKitUser>` | Active editor collaborators, excluding self. Populated from `join()` and maintained by editor join/leave broadcasts. |
| `all`    | `Map<string, CollabKitUser>` | Explicit paginated cache, excluding self. Only populated by `users.list(...)`.                                       |

<Note>
  Viewers are connected users, but they are not active collaborators. Viewer joins and leaves do not update `users.active`.
</Note>

## Methods

### `get({ userId? })`

Fetch one user from the server. This returns the user in the response, but does not populate `users.all`.

```typescript theme={null}
const me = await client.users.get();
const user = await client.users.get({ userId: 'user-002' });
```

### `list({ pageSize, offset, search })`

Fetch a page of users over HTTP and populate `users.all` with the returned users, excluding self.

```typescript theme={null}
const page = await client.users.list({
  pageSize: 100,
  offset: 0,
  search: 'ishita',
});

console.log(page.users);
console.log(page.total, page.hasMore);
console.log(client.users.all);
```

Return shape:

```typescript theme={null}
{
  users: CollabKitUser[];
  total: number;
  pageSize: number;
  offset: number;
  hasMore: boolean;
}
```

`pageSize` must be at most `100`; the SDK throws before making a network request if it is larger.

## Events

User lifecycle events refer to active editors, not all connected viewers.

```typescript theme={null}
client.users.on('userJoined', (user) => {
  console.log(`${user.name} became active`);
});

client.users.on('userLeft', (user) => {
  console.log(`${user.name} is no longer active`);
});
```

| Event         | Payload         | Description                              |
| ------------- | --------------- | ---------------------------------------- |
| `userJoined`  | `CollabKitUser` | An editor became active.                 |
| `userLeft`    | `CollabKitUser` | An editor stopped being active.          |
| `userCreated` | `CollabKitUser` | A new user record was added to the room. |
| `userUpdated` | `CollabKitUser` | A tracked user's fields changed.         |
| `userDeleted` | `CollabKitUser` | A tracked user was removed.              |

## Individual User

Each user in `users.active`, `users.all`, or `client.currentUser` is a `CollabKitUser` instance.

### Properties

| Property          | Type       | Description                     |                                 |
| ----------------- | ---------- | ------------------------------- | ------------------------------- |
| `id`              | `string`   | Unique user ID                  |                                 |
| `name`            | `string`   | Display name                    |                                 |
| `status`          | \`'online' | 'offline'\`                     | Current connection status       |
| `profile_picture` | \`string   | undefined\`                     | Avatar URL                      |
| `joined_at`       | \`string   | undefined\`                     | Last time the user came online  |
| `left_at`         | \`string   | undefined\`                     | Last time the user went offline |
| `following`       | `string[]` | User IDs this user is following |                                 |
| `followers`       | `string[]` | User IDs following this user    |                                 |

### `update({ name, profilePicture })`

Update your own user profile. Users cannot update another user's profile.

```typescript theme={null}
await client.currentUser?.update({ name: 'Updated Name' });
```

### `delete()`

Delete your own user record.

```typescript theme={null}
await client.currentUser?.delete();
```

### `follow()`

Follow another user. Viewers and editors can both follow users.

```typescript theme={null}
const targetUser = client.users.active.get('user-002') ?? client.users.all.get('user-002');
await targetUser?.follow();
```

<Note>
  Following is limited to one user at a time. If you're already following someone and call `follow()` on a different user, call `unfollow()` first.
</Note>

### `unfollow()`

Stop following a user:

```typescript theme={null}
await targetUser?.unfollow();
```

## Example

```typescript theme={null}
await client.join({ role: 'viewer' });

// Active editors are available immediately after join.
renderActiveEditors([...client.users.active.values()]);

// Load all users only when the UI needs a browsable list.
const firstPage = await client.users.list({ pageSize: 100, offset: 0 });
renderAllUsers(firstPage.users);

client.users.on('userJoined', () => renderActiveEditors([...client.users.active.values()]));
client.users.on('userLeft', () => renderActiveEditors([...client.users.active.values()]));
```
