Choosing a backend
Choose persistence and attachment storage independently, with explicit factories bound to verified identity.
createChatHandler separates conversation persistence (ChatStore) from
attachment storage (StorageAdapter). Both are factories called after
authentication with the verified userId.
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.
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.