---
title: Publishing your adapter
description: Package, version, and publish your community Chat SDK adapter to npm.
type: guide
prerequisites:
  - /docs/contributing/building
  - /docs/contributing/testing
  - /docs/contributing/documenting
related:
  - /docs/adapters
---

## Package checklist

Before publishing, verify your `package.json` meets these requirements:

```json title="package.json" lineNumbers
{
  "name": "chat-adapter-matrix",
  "version": "1.0.0",
  "type": "module",
  "main": "./dist/index.js",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "import": "./dist/index.js"
    }
  },
  "files": ["dist"],
  "peerDependencies": {
    "chat": "^4.0.0"
  },
  "publishConfig": {
    "access": "public"
  },
  "keywords": ["chat-sdk", "chat-adapter", "matrix"],
  "license": "MIT"
}
```

| Field | Why it matters |
|-------|---------------|
| `"type": "module"` | ESM-only — matches the Chat SDK ecosystem |
| `"files": ["dist"]` | Only publish compiled output, keeping the package lean |
| `"exports"` | Explicit entry points for bundlers and Node.js |
| `"peerDependencies"` | Consumers provide their own `chat` instance |
| `"publishConfig"` | Required for scoped packages (`@your-scope/chat-adapter-*`) |
| `"keywords"` | Include `chat-sdk` and `chat-adapter` for npm discoverability |

## Naming conventions

| Convention | Example | When to use |
|------------|---------|-------------|
| Unscoped | `chat-adapter-matrix` | Most community adapters |
| Scoped | `@your-org/chat-adapter-matrix` | Optional — if you prefer publishing under your org's scope |

<Callout type="warn">
  The `@chat-adapter/` npm scope is reserved for Vercel-maintained adapters. Do not publish under this scope.
</Callout>

## Build and verify

Run a full build and verify everything compiles before publishing.

```sh title="Terminal"
# Build
npm run build

# Type-check
npm run typecheck

# Run tests
npm test
```

Inspect the package contents to make sure only `dist/` is included:

```sh title="Terminal"
npm pack --dry-run
```

You should see output like:

```
dist/index.js
dist/index.d.ts
dist/index.js.map
package.json
README.md
LICENSE
```

If you see `src/`, `node_modules/`, or test files in the output, update your `"files"` field or add a `.npmignore`.

## Versioning

Follow [semver](https://semver.org):

| Change | Bump | Example |
|--------|------|---------|
| Bug fix, internal refactor | `patch` | `1.0.0` → `1.0.1` |
| New feature, new export, new config option | `minor` | `1.0.0` → `1.1.0` |
| Breaking change (removed export, changed signature) | `major` | `1.0.0` → `2.0.0` |

When the Chat SDK releases a new major version, you'll need a major bump too if your adapter's peer dependency range changes.

## Publish to npm

```sh title="Terminal"
npm publish
```

For scoped packages published for the first time:

```sh title="Terminal"
npm publish --access public
```

## Peer dependency compatibility

Your adapter should declare `chat` as a peer dependency with a caret range:

```json
{
  "peerDependencies": {
    "chat": "^4.0.0"
  }
}
```

This means your adapter works with any `4.x` release. When the Chat SDK ships a new major version:

1. Test your adapter against the new version
2. Update the peer dependency range
3. Publish a new major version of your adapter

## Post-publish verification

After publishing, verify the package works for consumers:

```sh title="Terminal"
# Create a temp directory
mkdir /tmp/test-adapter && cd /tmp/test-adapter
npm init -y

# Install your adapter
npm install chat chat-adapter-matrix

# Verify the import works
node -e "import('chat-adapter-matrix').then(m => console.log(Object.keys(m)))"
```

You should see your exported symbols (`createMatrixAdapter`, `MatrixAdapter`, etc.).

## Keeping your adapter up to date

- Watch the [Chat SDK changelog](https://github.com/vercel/chat/releases) for new features and breaking changes
- Run your test suite against new Chat SDK releases before they ship to catch compatibility issues early
- When the `Adapter` interface adds new optional methods, consider implementing them to keep your adapter feature-complete

## Listing on chat-sdk.dev

Community adapters can be listed on the [Adapters](https://chat-sdk.dev/adapters) page by opening a PR that adds an entry to `apps/docs/adapters.json` in the [Chat SDK repo](https://github.com/vercel/chat). Your adapter's README is fetched from GitHub at build time and rendered on its dedicated page.

### Pin your README to a commit or tag

<Callout type="warn">
  The `readme` field **must** reference a specific commit SHA or tag — not a branch name like `main`.
</Callout>

The docs site re-renders on every deploy, so an unpinned `readme` would serve whatever currently sits at your default branch — including edits made after the listing PR was reviewed. Pinning freezes the rendered content at the state we approved; new content goes live through a follow-up PR that bumps the ref.

```json title="apps/docs/adapters.json"
{
  "name": "My Adapter",
  "slug": "my-adapter",
  "type": "platform",
  "community": true,
  "packageName": "chat-adapter-my-thing",
  "readme": "https://github.com/your-org/chat-adapter-my-thing/tree/v1.2.0"
}
```

Accepted `readme` formats:

| Format | Example |
|--------|---------|
| Repo root at a tag | `https://github.com/owner/repo/tree/v1.0.0` |
| Repo root at a commit | `https://github.com/owner/repo/tree/abc1234...` |
| Subpath in a monorepo | `https://github.com/owner/repo/tree/<ref>/packages/adapter` |

Unpinned refs (e.g., `tree/main`, or omitting `/tree/<ref>` entirely) will emit a build warning and are rejected during PR review.
