---
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
  - /docs/contributing/vendor-official
---

# Publishing your adapter



## Package checklist

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

`YOUR_PUBLISHED_ADAPTER_PACKAGE` is a placeholder for your adapter's npm package name. Replace it with a valid name you own before publishing, and use that exact name in the post-publish verification commands. Do not install the placeholder or an unrelated package with a similar name.

```json title="package.json" lineNumbers
{
  "name": "YOUR_PUBLISHED_ADAPTER_PACKAGE",
  "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"`   | Publishes ESM only, matching the Chat SDK packages            |
| `"files": ["dist"]`  | Publishes only compiled output, which keeps the package small |
| `"exports"`          | Declares explicit entry points for bundlers and Node.js       |
| `"peerDependencies"` | Lets 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 | Pattern                             | When to use                                    |
| ---------- | ----------------------------------- | ---------------------------------------------- |
| Unscoped   | `chat-adapter-PLATFORM`             | A unique, available name for your adapter      |
| Scoped     | `@YOUR_SCOPE/chat-adapter-PLATFORM` | An adapter published under a scope you control |

Replace `PLATFORM` and `YOUR_SCOPE` with your own values. These are naming patterns, not packages to install. New npm package names must be lowercase; see [npm's package name rules](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#name).

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

## Build and verify

Before publishing, build the package, type-check it, and run the tests.

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

# Type-check
npm run typecheck

# Run tests
npm test
```

Inspect the package contents to confirm that 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` |

If a new Chat SDK major version changes your adapter's peer dependency range, bump your adapter's major version too.

## 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 YOUR_PUBLISHED_ADAPTER_PACKAGE

# Verify the import works
node -e "import('YOUR_PUBLISHED_ADAPTER_PACKAGE').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.

<Callout type="info">
  Platform vendors should follow the [vendor-official guide](/docs/contributing/vendor-official) instead.
</Callout>

### 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 is on your default branch at that moment, including edits made after the listing PR was reviewed. Pinning keeps the rendered content at the version we approved. To publish new README content, open 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": "YOUR_PUBLISHED_ADAPTER_PACKAGE",
  "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, such as `tree/main` or a URL without `/tree/<ref>`, emit a build warning and are rejected during PR review.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)