Vercel Chat SDK expert guidance. Use when building multi-platform chat bots — Slack, Telegram, Microsoft Teams, Discord, Google Chat, GitHub, Linear — with a single codebase. Covers the Chat class, adapters, threads, messages, cards, modals, streaming, state management, and webhook setup.
npx skills add https://github.com/vercel/vercel-plugin --skill chat-sdk
Unified TypeScript SDK for building chat bots across Slack, Teams, Google Chat, Discord, Telegram, GitHub, Linear, and WhatsApp. Write bot logic once, deploy everywhere.
When Chat SDK is installed in a user project, inspect the published files that ship in node_modules:
node_modules/chat/docs/ # bundled docs
node_modules/chat/dist/index.d.ts # core API types
node_modules/chat/dist/jsx-runtime.d.ts # JSX runtime types
node_modules/chat/docs/contributing/ # adapter-authoring docs
node_modules/chat/docs/guides/ # framework/platform guides
If one of the paths below does not exist, that package is not installed in the project yet.
Read these before writing code:
node_modules/chat/docs/getting-started.mdx — install and setupnode_modules/chat/docs/usage.mdx — Chat config and lifecyclenode_modules/chat/docs/handling-events.mdx — event routing and handlersnode_modules/chat/docs/threads-messages-channels.mdx — thread/channel/message modelnode_modules/chat/docs/posting-messages.mdx — post, edit, delete, schedulenode_modules/chat/docs/streaming.mdx — AI SDK integration and streaming semanticsnode_modules/chat/docs/cards.mdx — JSX cardsnode_modules/chat/docs/actions.mdx — button/select interactionsnode_modules/chat/docs/modals.mdx — modal submit/close flowsnode_modules/chat/docs/slash-commands.mdx — slash command routingnode_modules/chat/docs/direct-messages.mdx — DM behavior and openDM()node_modules/chat/docs/files.mdx — attachments/uploadsnode_modules/chat/docs/state.mdx — persistence, locking, dedupenode_modules/chat/docs/adapters.mdx — cross-platform feature matrixnode_modules/chat/docs/api/chat.mdx — exact Chat APInode_modules/chat/docs/api/thread.mdx — exact Thread APInode_modules/chat/docs/api/message.mdx — exact Message APInode_modules/chat/docs/api/modals.mdx — modal element and event detailsFor the specific adapter or state package you are using, inspect that installed package's dist/index.d.ts export surface in node_modules.
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(),
dedupeTtlMs: 600_000,
});
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}`);
});
post(), stream(), subscribe(), setState(), startTyping()text, formatted, attachments, author info, and platform raw| Handler | Trigger |
|---------|---------|
| onNewMention | Bot @-mentioned in an unsubscribed thread |
| onDirectMessage | New DM in an unsubscribed DM thread |
| onSubscribedMessage | Any message in a subscribed thread |
| onNewMessage(regex) | Regex match in an unsubscribed thread |
| onReaction(emojis?) | Emoji added or removed |
| onAction(actionIds?) | Button clicks and select/radio interactions |
| onModalSubmit(callbackId?) | Modal form submitted |
| onModalClose(callbackId?) | Modal dismissed/cancelled |
| onSlashCommand(commands?) | Slash command invocation |
| onAssistantThreadStarted | Slack assistant thread opened |
| onAssistantContextChanged | Slack assistant context changed |
| onAppHomeOpened | Slack App Home opened |
| onMemberJoinedChannel | Slack member joined channel event |
Read node_modules/chat/docs/handling-events.mdx, node_modules/chat/docs/actions.mdx, node_modules/chat/docs/modals.mdx, and node_modules/chat/docs/slash-commands.mdx before wiring handlers. onDirectMessage behavior is documented in node_modules/chat/docs/direct-messages.mdx.
Pass any AsyncIterable<string> to thread.post() or thread.stream(). For AI SDK, prefer result.fullStream over result.textStream when available so step boundaries are preserved.
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.fullStream);
});
Key details:
streamingUpdateIntervalMs controls post+edit fallback cadencefallbackStreamingPlaceholderText defaults to "..."; set null to disableStreamChunk support is Slack-only; other adapters ignore non-text chunksSet jsxImportSource: "chat" in tsconfig.json.
Card components:
Card, CardText, Section, Fields, Field, Button, CardLink, LinkButton, Actions, Select, SelectOption, RadioSelect, Table, Image, DividerModal components:
Modal, TextInput, Select, SelectOption, RadioSelectawait 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>
);
| Platform | Package | Factory |
|---------|---------|---------|
| Slack | @chat-adapter/slack | createSlackAdapter |
| Microsoft Teams | @chat-adapter/teams | createTeamsAdapter |
| Google Chat | @chat-adapter/gchat | createGoogleChatAdapter |
| Discord | @chat-adapter/discord | createDiscordAdapter |
| GitHub | @chat-adapter/github | createGitHubAdapter |
| Linear | @chat-adapter/linear | createLinearAdapter |
| Telegram | @chat-adapter/telegram | createTelegramAdapter |
| WhatsApp Business Cloud | @chat-adapter/whatsapp | createWhatsAppAdapter |
| State backend | Package | Factory |
|--------------|---------|---------|
| Redis | @chat-adapter/state-redis | createRedisState |
| ioredis | @chat-adapter/state-ioredis | createIoRedisState |
| PostgreSQL | @chat-adapter/state-pg | createPostgresState |
| Memory | @chat-adapter/state-memory | createMemoryState |
chat-state-cloudflare-do@beeper/chat-adapter-matrixchat-adapter-imessage@bitbasti/chat-adapter-webex@resend/chat-sdk-adapterchat-adapter-baileysRead these published docs first:
node_modules/chat/docs/contributing/building.mdxnode_modules/chat/docs/contributing/testing.mdxnode_modules/chat/docs/contributing/publishing.mdxAlso inspect:
node_modules/chat/dist/index.d.ts — Adapter and related interfacesnode_modules/@chat-adapter/shared/dist/index.d.ts — shared errors and utilitiesdist/index.d.ts files — reference implementations for config and APIsA custom adapter needs request verification, webhook parsing, message/thread/channel operations, ID encoding/decoding, and a format converter. Use BaseFormatConverter from chat and shared utilities from @chat-adapter/shared.
Each registered adapter exposes bot.webhooks.<name>. Wire those directly to your HTTP framework routes. See node_modules/chat/docs/guides/slack-nextjs.mdx and node_modules/chat/docs/guides/discord-nuxt.mdx for framework-specific route patterns.
Use when building HTML email templates with React components, adding a visual email editor to an application using the React Email visual editor, rendering emails to HTML, or sending emails with Resend. Covers welcome emails, password resets, notifications, order confirmations, newsletters, transactional emails, and the embeddable email editor component.
MCP Agent Mail - Mail-like coordination layer for multi-agent workflows. Identities, inbox/outbox, file reservations, contact policies, threaded messaging, pre-commit guard, Human Overseer, static exports, disaster recovery. Git+SQLite backed. Python/FastMCP.
Chat UI building blocks for React/Next.js from ui.inference.sh. Components: container, messages, input, typing indicators, avatars. Capabilities: chat interfaces, message lists, input handling, streaming. Use for: building custom chat UIs, messaging interfaces, AI assistants. Triggers: chat ui, chat component, message list, chat input, shadcn chat, react chat, chat interface, messaging ui, conversation ui, chat building blocks
\"Chat UI building blocks for React/Next.js from ui.inference.sh. Components: container, messages, input, typing indicators, avatars. Capabilities: chat interfaces, message lists, input handling, streaming. Use for: building custom chat UIs, messaging interfaces, AI assistants. Triggers: chat ui, chat component, message list, chat input, shadcn chat,\" react chat, chat interface, messaging ui, conversation ui, chat building blocks
Add DeltaChat channel integration via @deltachat/stdio-rpc-server. Native adapter — no Chat SDK bridge. Email-based messaging with end-to-end encryption.
Add Resend (email) channel integration via Chat SDK.
Build a Zoom meeting bot, recorder, or real-time media workflow. Use when joining meetings programmatically, processing live media or transcripts, or combining Meeting SDK, RTMS, and backend services.
Reference skill for Zoom Meeting SDK. Use after routing to a meeting-embed workflow when implementing real Zoom meeting joins, platform-specific SDK behavior, auth and join flows, waiting room issues, or meeting bot patterns.
Take vercel/chat-sdk from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.