Skip to main content
The following page details an example app that deploys a LangChain deep agent on Cloudflare Workers: streaming chat UI, subagents, and thread history, all backed by the Agent Streaming Protocol implemented as Worker routes (HTTP + SSE). The React SPA is served from the same Worker via Workers Assets. No separate backend process: one Worker serves the SPA and the protocol API. Source: js-cloudflare in the deployment cookbook.

Deploy to Cloudflare

1

Install and build

cd js-cloudflare
cp .env.example .dev.vars   # set OPENAI_API_KEY for local dev
pnpm install
pnpm build
2

Configure secrets

npx wrangler login
npx wrangler secret put OPENAI_API_KEY
3

Deploy

pnpm run deploy
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)

MethodPathPurpose
POST/api/threads/:threadId/commandsAccept protocol commands (run.start, …) and start agent runs
POST/api/threads/:threadId/streamSSE stream of protocol events for a run
GET / POST/api/threads/:threadId/stateRead and bootstrap checkpointed thread state

Optional (sidebar)

MethodPathPurpose
GET/api/threadsList threads known to the checkpointer
DELETE/api/threads/:threadIdDelete a thread’s session and checkpoints
POST/api/threads/:threadId/historyPaginated checkpoint history

Request flow

  1. Bootstrap thread state (GET/POST /state).
  2. On submit, the SDK sends run.start to /commands and receives a run_id.
  3. The Worker starts the graph run and fans each protocol event into the thread’s Durable Object.
  4. The SDK subscribes to /stream (SSE). The DO replays buffered events and stays attached for live frames, even across Worker isolate restarts.
  5. Subagent (task) runs emit namespaced events surfaced as stream.subagents.

Cloudflare backend design

ConcernImplementation
FrontendVite + React SPA (src/)
API layerHono routes in worker/index.ts
RuntimeWorkers V8 + nodejs_compat
SSE replayPer-thread Durable Object (ThreadSession)
Agent runsWorker isolate; protocol events POSTed to the DO
Static assetsWorkers Assets (wrangler.jsoncassets)
Secretswrangler secret / .dev.vars
Local devvite (Cloudflare Vite plugin runs the Worker runtime)
The split between Worker (agent + checkpointer) and Durable Object (SSE event log) is the main design choice on Cloudflare. Worker isolates are ephemeral, so replay buffers live in Durable Objects rather than process memory.

Production persistence

Out of the box, the agent uses an in-memory MemorySaver 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:
  1. Swap in a durable checkpointer (for example Postgres via Hyperdrive, or a custom DO-backed store).
  2. Keep per-thread Durable Objects for SSE replay (or persist the event log to DO storage / KV for long-lived reconnects).
For more information, see checkpointer libraries and add memory / persistence.

Local development

cp .env.example .dev.vars   # set OPENAI_API_KEY
pnpm install
pnpm dev
Open http://localhost:5173. The Cloudflare Vite plugin runs your Worker in the Workers runtime during dev, so /api/* routes behave like production.
pnpm build    # production build (client + worker)
pnpm preview  # preview the production build locally
pnpm typecheck

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) with researcher and math-whiz subagents 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