---
title: Creating a Chat Instance
description: Initialize the Chat class with adapters, state, and configuration options.
type: guide
prerequisites:
  - /docs/getting-started
related:
  - /docs/handling-events
  - /docs/adapters
  - /docs/state
---

# Creating a Chat Instance



The `Chat` class is the main entry point for your bot. It coordinates adapters, routes events to your handlers, and manages thread state.

## Basic setup

```typescript title="lib/bot.ts" lineNumbers
import { Chat } from "chat";
import { createSlackAdapter } from "@chat-adapter/slack";
import { createRedisState } from "@chat-adapter/state-redis";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    slack: createSlackAdapter(),
  },
  state: createRedisState(),
});

bot.onNewMention(async (thread) => {
  await thread.subscribe();
  await thread.post("Hello! I'm listening to this thread.");
});
```

<Callout type="info">
  This example uses Redis. Chat SDK also supports [PostgreSQL](/docs/state/postgres) and [ioredis](/docs/state/ioredis) as production state adapters. See [State Adapters](/docs/state) for all options.
</Callout>

Each adapter factory auto-detects credentials from environment variables (`SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET`, `REDIS_URL`, etc.), so you can get started with zero config. Pass explicit values to override.

## Multiple [adapters](/adapters)

Register multiple [adapters](/adapters) to deploy your bot across platforms simultaneously:

```typescript title="lib/bot.ts" lineNumbers
import { Chat } from "chat";
import { createSlackAdapter } from "@chat-adapter/slack";
import { createTeamsAdapter } from "@chat-adapter/teams";
import { createDiscordAdapter } from "@chat-adapter/discord";
import { createRedisState } from "@chat-adapter/state-redis";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    slack: createSlackAdapter(),
    teams: createTeamsAdapter(),
    discord: createDiscordAdapter(),
  },
  state: createRedisState(),
});
```

Your event handlers work identically across all registered adapters — the SDK normalizes messages, threads, and reactions into a consistent format.

## Configuration options

| Option                             | Type                                                            | Default    | Description                                                                                                                                                     |
| ---------------------------------- | --------------------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userName`                         | `string`                                                        | *required* | Default bot username across all adapters                                                                                                                        |
| `adapters`                         | `Record<string, Adapter>`                                       | *required* | Map of adapter name to adapter instance                                                                                                                         |
| `state`                            | `StateAdapter`                                                  | *required* | State adapter for subscriptions and locking                                                                                                                     |
| `logger`                           | `Logger \| LogLevel`                                            | `"info"`   | Logger instance or log level (`"debug"`, `"info"`, `"warn"`, `"error"`, `"silent"`)                                                                             |
| `dedupeTtlMs`                      | `number`                                                        | `300000`   | TTL in ms for message deduplication (5 minutes)                                                                                                                 |
| `streamingUpdateIntervalMs`        | `number`                                                        | `500`      | Update interval in ms for post+edit streaming                                                                                                                   |
| `fallbackStreamingPlaceholderText` | `string \| null`                                                | `"..."`    | Placeholder text while streaming starts. Set to `null` to skip                                                                                                  |
| `onLockConflict`                   | `'drop' \| 'force' \| (threadId, message) => 'drop' \| 'force'` | `"drop"`   | Behavior when a thread lock is already held. `'force'` releases the existing lock and re-acquires it, enabling interrupt/steerability for long-running handlers |

## Accessing [adapters](/adapters)

Use `getAdapter` to access platform-specific APIs when you need functionality beyond the unified interface:

```typescript title="lib/bot.ts" lineNumbers
import type { SlackAdapter } from "@chat-adapter/slack";

const slack = bot.getAdapter("slack") as SlackAdapter;
await slack.setSuggestedPrompts(channelId, threadTs, [
  { title: "Get started", message: "What can you help me with?" },
]);
```

## Webhook routing

The `webhooks` property provides type-safe handlers for each registered adapter. Wire these up to your HTTP framework's routes:

```typescript title="app/api/webhooks/slack/route.ts" lineNumbers
import { bot } from "@/lib/bot";

export const POST = bot.webhooks.slack;
```

```typescript title="app/api/webhooks/teams/route.ts" lineNumbers
import { bot } from "@/lib/bot";

export const POST = bot.webhooks.teams;
```

## Lifecycle

The Chat instance initializes lazily on the first webhook. You can also initialize manually:

```typescript title="lib/bot.ts" lineNumbers
await bot.initialize();
```

For graceful shutdown (e.g. in serverless teardown), call `shutdown`:

```typescript title="lib/bot.ts" lineNumbers
await bot.shutdown();
```

## Singleton pattern

Register a singleton when you need to access the Chat instance from multiple files:

```typescript title="lib/bot.ts" lineNumbers
const bot = new Chat({ /* ...config */ }).registerSingleton();
export default bot;
```

```typescript title="lib/utils.ts" lineNumbers
import { Chat } from "chat";

const bot = Chat.getSingleton();
```

## Direct messaging

Open a DM thread with a user by passing their platform user ID or an `Author` object:

```typescript title="lib/bot.ts" lineNumbers
const dm = await bot.openDM("slack:U123ABC");
await dm.post("Hey! Just wanted to follow up on your request.");
```

## Channel access

Get a channel directly by its ID:

```typescript title="lib/bot.ts" lineNumbers
const channel = bot.channel("slack:C123ABC");
await channel.post("Announcement: deploy complete!");
```
