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

# Typing Indicators

> Show real-time typing status in chat apps with the CometChat JavaScript SDK.

## Send a Typing Indicator

### Start Typing

Use `startTyping()` with a [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) object to notify the receiver that you're typing.

<Tabs>
  <Tab title="Start Typing User (TypeScript)">
    ```typescript theme={null}
    let receiverId: string = "UID";
    let receiverType: string = CometChat.RECEIVER_TYPE.USER;

    let typingNotification: CometChat.TypingIndicator = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.startTyping(typingNotification);

    ```
  </Tab>

  <Tab title="Start Typing User (JavaScript)">
    ```javascript theme={null}
    let receiverId = "UID";
    let receiverType = CometChat.RECEIVER_TYPE.USER;

    let typingNotification = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.startTyping(typingNotification);
    ```
  </Tab>

  <Tab title="Start Typing Group (TypeScript)">
    ```typescript theme={null}
    let receiverId: string = "GUID";
    let receiverType: string = CometChat.RECEIVER_TYPE.GROUP;

    let typingNotification: CometChat.TypingIndicator = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.startTyping(typingNotification);

    ```
  </Tab>

  <Tab title="Start Typing Group (JavaScript)">
    ```javascript theme={null}
    let receiverId = "GUID";
    let receiverType = CometChat.RECEIVER_TYPE.GROUP;

    let typingNotification = new CometChat.TypingIndicator(receiverId,receiverType);
    CometChat.startTyping(typingNotification);
    ```
  </Tab>
</Tabs>

`startTyping()` returns `void` — the typing indicator is sent as a fire-and-forget operation.

### Stop Typing

Use `endTyping()` to notify the receiver that you've stopped typing.

<Tabs>
  <Tab title="Stop Typing User (TypeScript)">
    ```typescript theme={null}
    let receiverId: string = "UID";
    let receiverType: string = CometChat.RECEIVER_TYPE.USER;

    let typingNotification: CometChat.TypingIndicator = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.endTyping(typingNotification);

    ```
  </Tab>

  <Tab title="Stop Typing User (JavaScript)">
    ```javascript theme={null}
    let receiverId = "UID";
    let receiverType = CometChat.RECEIVER_TYPE.USER;

    let typingNotification = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.endTyping(typingNotification);
    ```
  </Tab>

  <Tab title="Stop Typing Group (TypeScript)">
    ```typescript theme={null}
    let receiverId: string = "GUID";
    let receiverType: string = CometChat.RECEIVER_TYPE.GROUP;

    let typingNotification: CometChat.TypingIndicator = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.endTyping(typingNotification);

    ```
  </Tab>

  <Tab title="Stop Typing Group (JavaScript)">
    ```javascript theme={null}
    let receiverId = "GUID";
    let receiverType = CometChat.RECEIVER_TYPE.GROUP;

    let typingNotification = new CometChat.TypingIndicator(receiverId, receiverType);
    CometChat.endTyping(typingNotification);
    ```
  </Tab>
</Tabs>

`endTyping()` returns `void` — the typing indicator is sent as a fire-and-forget operation.

<Note>
  Use `setMetadata()` on
  [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator) to pass
  additional custom data. Retrieve it with `getMetadata()` on the receiver side.
</Note>

## Real-time Typing Indicators

Use `onTypingStarted` and `onTypingEnded` in `MessageListener` to receive typing events.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    let listenerId: string = "UNIQUE_LISTENER_ID";

    CometChat.addMessageListener(
    listenerId,
    new CometChat.MessageListener({
    onTypingStarted: (typingIndicator: CometChat.TypingIndicator) => {
    console.log("Typing started :", typingIndicator);
    },
    onTypingEnded: (typingIndicator: CometChat.TypingIndicator) => {
    console.log("Typing ended :", typingIndicator);
    }
    })
    );

    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    let listenerId = "UNIQUE_LISTENER_ID";

    CometChat.addMessageListener(
    listenerId,
    new CometChat.MessageListener({
      onTypingStarted: typingIndicator => {
        console.log("Typing started :", typingIndicator);
      },
      onTypingEnded: typingIndicator => {
        console.log("Typing ended :", typingIndicator);
      }
    })
    );
    ```
  </Tab>
</Tabs>

The received object is a [`TypingIndicator`](/sdk/reference/auxiliary#typingindicator).

<Warning>
  Always remove message listeners when they're no longer needed (e.g., on component unmount or page navigation). Failing to remove listeners can cause memory leaks and duplicate event handling.

  ```javascript theme={null}
  CometChat.removeMessageListener("UNIQUE_LISTENER_ID");
  ```
</Warning>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Delivery & Read Receipts" icon="check-double" href="/sdk/javascript/delivery-read-receipts">
    Track when messages are delivered and read
  </Card>

  <Card title="Transient Messages" icon="bolt" href="/sdk/javascript/transient-messages">
    Send ephemeral real-time messages like live reactions
  </Card>
</CardGroup>
