Chat SDK
Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, GitHub, and Linear. Write bot logic once, deploy everywhere.
Critical: Read the bundled docs
The chat package ships with full documentation in node_modules/chat/docs/ and TypeScript source types. Always read these before writing code:
node_modules/chat/docs/ # Full documentation (MDX files)
node_modules/chat/dist/ # Built types (.d.ts files)
Key docs to read based on task:
docs/getting-started.mdx — setup guides
docs/usage.mdx — event handlers, threads, messages, channels
docs/streaming.mdx — AI streaming with AI SDK
docs/cards.mdx — JSX interactive cards
docs/actions.mdx — button/dropdown handlers
docs/modals.mdx — form dialogs (Slack only)
docs/adapters/*.mdx — platform-specific adapter setup
docs/state/*.mdx — state adapter config (Redis, ioredis, memory)
Also read the TypeScript types from node_modules/chat/dist/ to understand the full API surface.
Quick start
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({
botToken: process.env.SLACK_BOT_TOKEN!,
signingSecret: process.env.SLACK_SIGNING_SECRET!,
}),
},
state: createRedisState({ url: process.env.REDIS_URL! }),
});
bot.onNewMention(async (thread) => {
await thread.subscribe();
await thread.post("Hello! I'm listening to this thread.");
});
bot.onSubscribedMessage(async (thread, message) => {
await thread.post(`You said: ${message.text}`);
});
Core concepts
- Chat — main entry point, coordinates adapters and routes events
- Adapters — platform-specific (Slack, Teams, GChat, Discord, GitHub, Linear)
- State — pluggable persistence (Redis for prod, memory for dev)
- Thread — conversation thread with
post(), subscribe(), startTyping()
- Message — normalized format with
text, formatted (mdast AST), raw
- Channel — container for threads, supports listing and posting
Event handlers
| Handler |
Trigger |
onNewMention |
Bot @-mentioned in unsubscribed thread |
onSubscribedMessage |
Any message in subscribed thread |
onNewMessage(regex) |
Messages matching pattern in unsubscribed threads |
onSlashCommand("/cmd") |
Slash command invocations |
onReaction(emojis) |
Emoji reactions added/removed |
onAction(actionId) |
Button clicks and dropdown selections |
onAssistantThreadStarted |
Slack Assistants API thread opened |
onAppHomeOpened |
Slack App Home tab opened |
Streaming
Pass any AsyncIterable<string> to thread.post(). Works with AI SDK's textStream:
import { ToolLoopAgent } from "ai";
const agent = new ToolLoopAgent({ model: "anthropic/claude-4.5-sonnet" });
bot.onNewMention(async (thread, message) => {
const result = await agent.stream({ prompt: message.text });
await thread.post(result.textStream);
});
Cards (JSX)
Set jsxImportSource: "chat" in tsconfig. Components: Card, CardText, Button, Actions, Fields, Field, Select, SelectOption, Image, Divider, LinkButton, Section, RadioSelect.
await thread.post(
<Card title="Order #1234">
<CardText>Your order has been received!</CardText>
<Actions>
<Button id="approve" style="primary">Approve</Button>
<Button id="reject" style="danger">Reject</Button>
</Actions>
</Card>
);
Packages
| Package |
Purpose |
chat |
Core SDK |
@chat-adapter/slack |
Slack |
@chat-adapter/teams |
Microsoft Teams |
@chat-adapter/gchat |
Google Chat |
@chat-adapter/discord |
Discord |
@chat-adapter/github |
GitHub Issues |
@chat-adapter/linear |
Linear Issues |
@chat-adapter/state-redis |
Redis state (production) |
@chat-adapter/state-ioredis |
ioredis state (alternative) |
@chat-adapter/state-memory |
In-memory state (development) |
Webhook setup
Each adapter exposes a webhook handler via bot.webhooks.{platform}. Wire these to your HTTP framework's routes (e.g. Next.js API routes, Hono, Express).
1---2name: chat-sdk3description: Build multi-platform chat bots with Chat SDK (`chat` npm package). Use when developers want to (1) Build a Slack, Teams, Google Chat, Discord, GitHub, or Linear bot, (2) Use the Chat SDK to handle mentions, messages, reactions, slash commands, cards, modals, or streaming, (3) Set up webhook handlers for chat platforms, (4) Send interactive cards or stream AI responses to chat platforms. Triggers on "chat sdk", "chat bot", "slack bot", "teams bot", "discord bot", "@chat-adapter", building bots that work across multiple chat platforms.4license: Sustainable Use License 1.05---67# Chat SDK89Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, GitHub, and Linear. Write bot logic once, deploy everywhere.1011## Critical: Read the bundled docs1213The `chat` package ships with full documentation in `node_modules/chat/docs/` and TypeScript source types. **Always read these before writing code:**1415```16node_modules/chat/docs/ # Full documentation (MDX files)17node_modules/chat/dist/ # Built types (.d.ts files)18```1920Key docs to read based on task:21- `docs/getting-started.mdx` — setup guides22- `docs/usage.mdx` — event handlers, threads, messages, channels23- `docs/streaming.mdx` — AI streaming with AI SDK24- `docs/cards.mdx` — JSX interactive cards25- `docs/actions.mdx` — button/dropdown handlers26- `docs/modals.mdx` — form dialogs (Slack only)27- `docs/adapters/*.mdx` — platform-specific adapter setup28- `docs/state/*.mdx` — state adapter config (Redis, ioredis, memory)2930Also read the TypeScript types from `node_modules/chat/dist/` to understand the full API surface.3132## Quick start3334```typescript35import { Chat } from "chat";36import { createSlackAdapter } from "@chat-adapter/slack";37import { createRedisState } from "@chat-adapter/state-redis";3839const bot = new Chat({40 userName: "mybot",41 adapters: {42 slack: createSlackAdapter({43 botToken: process.env.SLACK_BOT_TOKEN!,44 signingSecret: process.env.SLACK_SIGNING_SECRET!,45 }),46 },47 state: createRedisState({ url: process.env.REDIS_URL! }),48});4950bot.onNewMention(async (thread) => {51 await thread.subscribe();52 await thread.post("Hello! I'm listening to this thread.");53});5455bot.onSubscribedMessage(async (thread, message) => {56 await thread.post(`You said: ${message.text}`);57});58```5960## Core concepts6162- **Chat** — main entry point, coordinates adapters and routes events63- **Adapters** — platform-specific (Slack, Teams, GChat, Discord, GitHub, Linear)64- **State** — pluggable persistence (Redis for prod, memory for dev)65- **Thread** — conversation thread with `post()`, `subscribe()`, `startTyping()`66- **Message** — normalized format with `text`, `formatted` (mdast AST), `raw`67- **Channel** — container for threads, supports listing and posting6869## Event handlers7071| Handler | Trigger |72|---------|---------|73| `onNewMention` | Bot @-mentioned in unsubscribed thread |74| `onSubscribedMessage` | Any message in subscribed thread |75| `onNewMessage(regex)` | Messages matching pattern in unsubscribed threads |76| `onSlashCommand("/cmd")` | Slash command invocations |77| `onReaction(emojis)` | Emoji reactions added/removed |78| `onAction(actionId)` | Button clicks and dropdown selections |79| `onAssistantThreadStarted` | Slack Assistants API thread opened |80| `onAppHomeOpened` | Slack App Home tab opened |8182## Streaming8384Pass any `AsyncIterable<string>` to `thread.post()`. Works with AI SDK's `textStream`:8586```typescript87import { ToolLoopAgent } from "ai";88const agent = new ToolLoopAgent({ model: "anthropic/claude-4.5-sonnet" });8990bot.onNewMention(async (thread, message) => {91 const result = await agent.stream({ prompt: message.text });92 await thread.post(result.textStream);93});94```9596## Cards (JSX)9798Set `jsxImportSource: "chat"` in tsconfig. Components: `Card`, `CardText`, `Button`, `Actions`, `Fields`, `Field`, `Select`, `SelectOption`, `Image`, `Divider`, `LinkButton`, `Section`, `RadioSelect`.99100```tsx101await thread.post(102 <Card title="Order #1234">103 <CardText>Your order has been received!</CardText>104 <Actions>105 <Button id="approve" style="primary">Approve</Button>106 <Button id="reject" style="danger">Reject</Button>107 </Actions>108 </Card>109);110```111112## Packages113114| Package | Purpose |115|---------|---------|116| `chat` | Core SDK |117| `@chat-adapter/slack` | Slack |118| `@chat-adapter/teams` | Microsoft Teams |119| `@chat-adapter/gchat` | Google Chat |120| `@chat-adapter/discord` | Discord |121| `@chat-adapter/github` | GitHub Issues |122| `@chat-adapter/linear` | Linear Issues |123| `@chat-adapter/state-redis` | Redis state (production) |124| `@chat-adapter/state-ioredis` | ioredis state (alternative) |125| `@chat-adapter/state-memory` | In-memory state (development) |126127## Webhook setup128129Each adapter exposes a webhook handler via `bot.webhooks.{platform}`. Wire these to your HTTP framework's routes (e.g. Next.js API routes, Hono, Express).