ai-persistence/build-cloudflare-adapter

Implements TanStack AI chat persistence on Cloudflare Workers using D1 and Durable Objects.

3.1k|316|Updated Oct 8, 2025
One-click install
npx skills add https://github.com/TanStack/ai --skill ai-persistence-build-cloudflare-adapter
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: ai-persistence/build-cloudflare-adapter
Source: https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence/build-cloudflare-adapter
Command: npx skills add https://github.com/TanStack/ai --skill ai-persistence-build-cloudflare-adapter

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Cloudflare Workers expose D1 database bindings only per request, so standard module-scope persistence adapters cannot work. This Skill writes a chat-persistence.ts factory into a Worker that builds TanStack AI chat persistence from the request's D1 binding, plus an optional Durable Object lock store for cross-isolate mutual exclusion.

Core Features & Use Cases

  • Per-request persistence factory: Generates a chatPersistence(env.DB) factory exporting a ChatPersistence with messages, runs, interrupts, and metadata stores against raw D1 or Drizzle.
  • D1 migrations: Emits a numbered SQL migration file with chat_threads, chat_runs, chat_interrupts, and chat_metadata tables, applied via wrangler d1 migrations apply.
  • Durable Object lock store: Implements a lease-based LockStore with expiry, alarm reclamation, and AbortSignal propagation for coordination across Worker isolates.
  • Use Case: A team deploying a streaming chat app on Cloudflare Workers needs durable conversation history and run resumption; this Skill scaffolds the persistence layer, wrangler bindings, and conformance tests against Miniflare.

Quick Start

Ask the AI to add TanStack AI chat persistence to your Cloudflare Worker using its D1 binding and wrangler configuration.

Frequently Asked Questions about ai-persistence/build-cloudflare-adapter

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I add chat persistence to a Cloudflare Worker with D1?

Export a factory function that builds a ChatPersistence from the request's D1 binding, since bindings are unavailable at module scope. Implement the messages, runs, interrupts, and metadata stores against d1.prepare(sql).bind(...), then pass the result to withPersistence middleware.

Should I use raw D1 or Drizzle for Cloudflare chat persistence?

Use Drizzle if the app already depends on drizzle-orm and has a schema file, wrapping the binding with drizzle(env.DB, { schema }). Otherwise implement the four stores directly against raw D1 prepared statements, which mirror the node:sqlite walkthrough since D1 speaks SQLite.

Why can't I create the D1 persistence adapter at module scope?

Cloudflare D1 bindings only exist per request through the env argument, so a module-scope const cannot access them. The adapter must be a factory called inside the fetch handler; building it per request is cheap because stores hold no state beyond the binding.

When do I need a Durable Object lock store with D1 persistence?

Add a Durable Object LockStore only when middleware needs mutual exclusion across Worker isolates, since InMemoryLockStore provides none. It uses leases with expiry and alarms so a crashed owner cannot block a key forever.

How do I test a Cloudflare D1 persistence adapter?

Run runPersistenceConformance from @tanstack/ai-persistence/testkit against a Miniflare D1 binding with the migration applied, resetting between runs. Declare unimplemented optional runs methods in skipMethods and skipped generation stores in skip.