Choosing a backend
createChatHandler separates conversation persistence (ChatStore) from
attachment storage (StorageAdapter). Both are factories called after
authentication with the verified userId.
code
type ChatStoreFactory = (userId: string) => ChatStore;
type StorageAdapterFactory = (userId: string) => StorageAdapter;Options
| Need | Factory |
|---|---|
| Self-hosted Postgres conversations | createDrizzleChatStore() |
| Private Supabase attachments | createSupabaseStorage() |
| Hosted conversations | createHostedChatStore({ apiKey }) |
| Hosted attachments | createHostedStorage({ apiKey }) |
| Custom database/object store | Your own user-bound factory |
Persistence is currently required; there is no silent default store. Storage is optional and uploads are disabled when it is absent.
code
export const { GET, POST, DELETE } = createChatHandler({
getUserId: getChatUserId,
model,
store: createDrizzleChatStore(),
storage: createSupabaseStorage(),
});Mix the axes deliberately: Drizzle plus Supabase, hosted store plus custom storage, or fully custom implementations. All custom stores/adapters must uphold the ownership and private-attachment invariants.