> ## 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.

# Comments System

> Add threaded comments with reactions and user tagging to your app.

This guide shows you how to build a complete commenting system with threaded replies, emoji reactions, and user mentions -- all synced in real time.

## What You'll Build

* A threaded comment feed with replies
* Emoji reactions on comments and replies
* User tagging with notifications
* Real-time sync across all participants

## Prerequisites

* A CollabKit server running with a room and users created
* `@collab-kit/client` and `@collab-kit/utils` installed

## Step 1: Set Up the Client

```typescript theme={null}
import CollabKitClient from '@collab-kit/client';

const client = new CollabKitClient({
  serverUrl: 'https://api.collab-kit.com',
  authToken: '<jwt-token>',
});

await client.join({ role: 'editor' });
```

<Note>
  Comment writes require an editor session. Viewers receive comment updates, but cannot create comments, replies, reactions, or tags.
</Note>

## Step 2: Load Existing Comments

```typescript theme={null}
const comments = await client.comments.getAll();
comments.forEach(renderComment);
```

## Step 3: Add a Comment

```typescript theme={null}
async function addComment(text: string, taggedUserIds?: string[]) {
  const comment = await client.comments.add(text, {
    tags: taggedUserIds,
  });

  // Set up per-comment listener
  comment.on('update', (updated) => {
    rerenderComment(updated);
  });

  renderComment(comment);
  return comment;
}
```

## Step 4: Reply to a Comment

Comments support one level of nesting:

```typescript theme={null}
async function replyToComment(comment, text: string) {
  const reply = await comment.reply(text);
  renderReply(comment.id, reply);
  return reply;
}
```

## Step 5: Add Reactions

```typescript theme={null}
async function addReaction(comment, emoji: string) {
  await comment.addReaction(emoji);
}

async function removeReaction(comment, emoji: string) {
  await comment.deleteReaction(emoji);
}
```

## Step 6: Tag Users

```typescript theme={null}
async function tagUser(comment, userId: string) {
  await comment.addTag(userId);
}

// Listen for being tagged
client.currentUser?.on('commentTagged', (comment) => {
  showNotification(`You were tagged in: "${comment.text}"`);
});
```

## Step 7: Listen for Real-Time Updates

```typescript theme={null}
// New comment from another user
client.comments.on('add', (comment) => {
  renderComment(comment);
  comment.on('update', (updated) => rerenderComment(updated));
});

// Comment deleted by another user
client.comments.on('delete', (commentId) => {
  removeCommentFromUI(commentId);
});

// Comment updated (new reaction, reply, or tag)
client.comments.on('update', (comment) => {
  rerenderComment(comment);
});
```

## Next Steps

* Anchor comments to specific UI elements or text selections
* Add user @mention autocomplete using `client.users.list(...)` and `client.users.all`
* Combine with [stores](/guides/real-time-stores) to attach comments to specific entities
* Use [webhooks](/guides/webhooks-workflows) to send email notifications for tagged users
