# Thread

Each thread is a singleton, with its replies in `thread.messagePaginator`.

## Initialization

Get the thread's instance with `client.threads.ensure()` and activate it: its replies load on the first `activate()`. Call `client.threads.registerSubscriptions()` once, so threads get their events.

```js label="JavaScript"
client.threads.registerSubscriptions();

const thread = client.threads.ensure({ channel, parentMessage });

thread.activate();
```

To load threads from the server, query them. `watch: true` keeps their channels watched, so they get new replies.

```js label="JavaScript"
// One thread, by its parent message id
const queriedThread = await client.getThreadAndHydrate(
  { message_id: parentMessageId },
  { watch: true },
);

// Several threads
const { threads } = await client.queryThreadsAndHydrate({
  watch: true,
  limit: 10,
});
```

## Reading

```js label="JavaScript"
// Parent message, participants, reply count
const {
  parentMessage: parent,
  participants,
  replyCount,
} = thread.state.getLatestValue();

// Replies: the same API as channel messages
const { items: replies, hasMoreTail } =
  thread.messagePaginator.state.getLatestValue();
```

Subscribe to render changes:

```js label="JavaScript"
const unsubscribe = thread.messagePaginator.state.subscribeWithSelector(
  ({ items }) => ({ items }),
  ({ items }) => renderReplies(items),
);
```

## Active thread

Only active threads are refreshed after a reconnect (unless you're using `ThreadPaginator` too):

```js label="JavaScript"
// While the thread is on screen
const release = thread.activate();

// When the thread leaves the screen
release();
```

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/javascript/state-thread/](https://getstream.io/chat/docs/javascript/state-thread/).