skills/vercel/chat/chat-sdk

chat-sdk

SKILL.md

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, PostgreSQL, 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 or PostgreSQL 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-pg PostgreSQL state (production)
@chat-adapter/state-memory In-memory state (development)

Changesets (Release Flow)

This monorepo uses Changesets for versioning and changelogs. Every PR that changes a package's behavior must include a changeset.

pnpm changeset
# → select affected package(s) (e.g. @chat-adapter/slack, chat)
# → choose bump type: patch (fixes), minor (features), major (breaking)
# → write a short summary for the CHANGELOG

This creates a file in .changeset/ — commit it with the PR. When merged to main, the Changesets GitHub Action opens a "Version Packages" PR to bump versions and update CHANGELOGs. Merging that PR publishes to npm.

Building a custom adapter

To create a community or vendor adapter, implement the Adapter interface from chat and read:

  • docs/contributing/building.mdx — full step-by-step guide (uses a Matrix adapter as example)
  • docs/contributing/testing.mdx — testing your adapter
  • docs/contributing/publishing.mdx — npm naming conventions and publishing

The adapter must implement handleWebhook, parseMessage, postMessage, editMessage, deleteMessage, thread ID encoding/decoding, and a FormatConverter (extend BaseFormatConverter from chat). Use @chat-adapter/shared for error classes and message utilities.

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

Weekly Installs
464
Repository
vercel/chat
GitHub Stars
1.2K
First Seen
14 days ago
Installed on
codex456
opencode454
github-copilot453
amp453
gemini-cli453
cursor453