js-cloudflare in the deployment cookbook.
Deploy to Cloudflare
Wrangler uploads the Vite build (SPA) and the Worker script in one deploy.nodejs_compat and nodejs_compat_populate_process_env are enabled so LangChain can read OPENAI_API_KEY from the environment.
wrangler.jsonc registers the ThreadSession Durable Object with new_sqlite_classes, which is required on the Workers Free plan.
Required API endpoints
The app exposes the Agent Streaming Protocol under/api/threads/.... Routes are implemented in worker/index.ts with Hono.
Minimum (streaming chat)
| Method | Path | Purpose |
|---|---|---|
POST | /api/threads/:threadId/commands | Accept protocol commands (run.start, …) and start agent runs |
POST | /api/threads/:threadId/stream | SSE stream of protocol events for a run |
GET / POST | /api/threads/:threadId/state | Read and bootstrap checkpointed thread state |
Optional (sidebar)
| Method | Path | Purpose |
|---|---|---|
GET | /api/threads | List threads known to the checkpointer |
DELETE | /api/threads/:threadId | Delete a thread’s session and checkpoints |
POST | /api/threads/:threadId/history | Paginated checkpoint history |
Request flow
- Bootstrap thread state (
GET/POST /state). - On submit, the SDK sends
run.startto/commandsand receives arun_id. - The Worker starts the graph run and fans each protocol event into the thread’s Durable Object.
- The SDK subscribes to
/stream(SSE). The DO replays buffered events and stays attached for live frames, even across Worker isolate restarts. - Subagent (
task) runs emit namespaced events surfaced asstream.subagents.
Cloudflare backend design
| Concern | Implementation |
|---|---|
| Frontend | Vite + React SPA (src/) |
| API layer | Hono routes in worker/index.ts |
| Runtime | Workers V8 + nodejs_compat |
| SSE replay | Per-thread Durable Object (ThreadSession) |
| Agent runs | Worker isolate; protocol events POSTed to the DO |
| Static assets | Workers Assets (wrangler.jsonc → assets) |
| Secrets | wrangler secret / .dev.vars |
| Local dev | vite (Cloudflare Vite plugin runs the Worker runtime) |
Production persistence
Out of the box, the agent uses an in-memoryMemorySaver checkpointer (worker/agent/index.ts). That works for local dev and demos, but on Cloudflare (multiple isolates, cold starts) conversation state is not durable across deploys or isolates.
For production:
- Swap in a durable checkpointer (for example Postgres via Hyperdrive, or a custom DO-backed store).
- Keep per-thread Durable Objects for SSE replay (or persist the event log to DO storage / KV for long-lived reconnects).
Local development
/api/* routes behave like production.
Project layout
src/components/— chat UI (ChatApp,Chat,MessageThread,Subagents,ThreadHistory, …).src/lib/chat/threads-client.ts— browser thread bootstrap and sidebar helpers.worker/agent/— deep agent (createDeepAgent) withresearcherandmath-whizsubagents and mock tools.worker/server/— protocol helpers:runs.ts(start runs on the Worker),threads.ts(checkpointer-backed state),serialize.ts,registry.ts.worker/durable-objects/thread-session.ts— per-thread SSE event log (StreamChannel+matchesSubscription).worker/index.ts— Hono app: protocol routes + Worker export.wrangler.jsonc— Worker config:nodejs_compat, Durable Object bindings, SPA asset routing (run_worker_first: ["/api/*"]).
See also
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

