# Chatpack - single-fetch guide for AI builders & coding agents
> Chatpack (npm: `@chatpack/core`) is an open-source TypeScript chat backend:
> 1:1 and group conversations, messages, permissions, read-state, and
> real-time SSE.
> **Part 1 is the integration guide** - read it before generating any code
> that uses Chatpack. Part 2 covers writing a custom storage adapter (only
> needed when the official adapters don't fit).
>
> Humans: the prose quickstart lives in the README; this file trades prose
> for completeness.
Packages (all on npm):
| Package | What it is |
| -------------------------- | ------------------------------------------------------ |
| `@chatpack/core` | The engine: API, HTTP handler, SSE, plugins |
| `@chatpack/adapter-memory` | In-memory storage - demos/tests, single process only |
| `@chatpack/adapter-drizzle`| Postgres storage via Drizzle - production |
| `@chatpack/adapter-prisma` | Postgres storage via Prisma ORM 7 - server-only |
| `@chatpack/adapter-mysql` | MySQL 8 storage via Drizzle/mysql2 - server-side |
| `@chatpack/adapter-turso` | Turso/libSQL storage via Drizzle |
| `@chatpack/adapter-sqlite` | SQLite storage via Drizzle - local/single node |
| `@chatpack/adapter-supabase` | Server-side Supabase/Postgres storage |
| `@chatpack/next` | Next.js App Router mount helper (`toNextRouteHandlers`)|
| `@chatpack/client` | Framework-agnostic REST + SSE client (+ React hooks) |
| `@chatpack/cli` | Setup CLI: wires an existing app, or generates a starter|
| `@chatpack/transport-redis`| Redis pub/sub transport - multi-node SSE fan-out |
| `@chatpack/file` | Filepack-backed message attachments (uploads, media) |
Current releases include direct and group conversations, text messages,
permissions, read state and unread counts, SSE with reconnect gap-fill,
memory, Drizzle/Turso, and Supabase adapters, Redis event fan-out, typing/presence/receipts, reactions,
quote-replies, participant-scoped search, `afterMessageMutation`, the browser
client with React hooks and polling fallback, `@chatpack/cli init` (wires an
existing app, or generates a Next.js/Hono/Express starter),
Filepack-backed file attachments via `@chatpack/file`, invite links with join
requests, public channels (a browsable directory of public groups), mentions,
and message forwarding.
`@chatpack/adapter-prisma` supports Prisma ORM 7. Install it with
`@prisma/client`, `@prisma/adapter-pg`, and `pg`. Copy its supplied Prisma
models and migration into your application, run Prisma format/validate,
migrate deploy, and generate. Create Prisma client in server code and pass it
to `prismaAdapter(client)`. Adapter does not read credentials, own client
lifecycle, or bundle generated client. Verified provider: PostgreSQL 16 with
Prisma 7.10.0. Prisma 8, MySQL, SQLite, MongoDB, CockroachDB, SQL Server,
Accelerate, edge, and serverless-driver combinations are unverified.
True message threads, push notification providers, and reusable React UI
components have not shipped. Multi-node presence is available with
`redisPresenceStore()` and the Redis transport.
## File attachments (`@chatpack/file`)
Attachments are an optional plugin backed by
[Filepack](https://github.com/chddaniel/filepack) (npm `@filepack/*`) -
Chatpack never stores bytes, signed URLs, or object keys. A message carries
only stable references in its metadata:
```ts
{ filepack: { version: 1, attachments: [{ id, name, contentType, size }] } }
```
Server (mounts Filepack routes below the Chatpack handler, default
`/api/chat/files`, and validates every referenced file before a message
persists):
```ts
import { createFileAttachmentPlugin } from "@chatpack/file";
const chat = chatpack({
storage, auth,
plugins: [createFileAttachmentPlugin({
filepack, // your FilepackApi instance
authorizeUpload: ({ actor, conversationId }) =>
isParticipant(actor.id, conversationId), // host policy - REQUIRED
})],
});
```
Browser: `createChatpackFileClient` from `@chatpack/file/client` wraps
`@filepack/client` for uploads, resume, and inline-vs-attachment delivery.
```ts
import { createChatpackFileClient } from "@chatpack/file/client";
const files = createChatpackFileClient({
basePath: "/api/chat/files",
// REQUIRED workaround for @filepack/client <= 0.1.1 in the browser: it
// stores globalThis.fetch unbound and calls it as a method, which Chrome's
// brand check rejects ("Illegal invocation"). The error surfaces as a
// mislabeled CLIENT_NETWORK_ERROR with no HTTP request sent. Passing fetch
// as an argument fixes every upload.
controlFetch: (input, init) => fetch(input, init),
});
```
Rules:
- Every attachment reference is validated on send AND edit, before
persistence: the file must be ready, bound to that conversation (Filepack
route metadata `conversationId`), authorized, and matching its reference
(`name`/`contentType`/`size`). Otherwise โ `422 MESSAGE_REJECTED`.
- File reads (`GET files/files?conversationId=`, metadata, downloads) require
the caller to be a Chatpack participant of that conversation AND the file
to belong to it; everything else is `404 FILE_UNAVAILABLE`.
- Exact Filepack byte-transfer routes (`PUT .../content`, versioned
`GET files/downloads/v1.*`) authenticate by Filepack's own short-lived
capability instead of the app session - required so `
`/`