Skip to content

Hosting on Cloudflare

Three Durable Object shapes — actions, realm-only, or both on one socket — and which serve call each one uses.

nice-code is built for the edge, and a Cloudflare Durable Object is its natural home: one addressable object per match / room / document, with hibernatable WebSockets, SQLite, and alarms. One serve… call folds the whole transport stack — the secure socket, the DO-storage crypto identity + TOFU pins, hibernation rehydrate, and the keepalive — into a call your DO’s four socket events forward to.

There are three shapes, depending on which planes your object hosts. Pick the row that matches, and follow the link for the complete Durable Object.

Your DO hosts…Serve withGuide
Actions only (typed RPC, server push)serveDurableObject@nice-code/action/platform/cloudflareAction → Cloudflare
A realm only (shared state, no actions)serveWireDurableObject@nice-code/wire/platform/cloudflare, with hostRealm registered on itServing a Realm
Both, on one socketserveDurableObject with protocols: [realms.protocol]Serving a Realm → both planes

The realm-only shape is the leanest: a DO that imports @nice-code/wire + @nice-code/realm and nothing else — no ActionRuntime, no channel — mirroring a createWireClient browser client exactly. Add actions later by switching the serve call to the action host and registering the same realms.protocol on it; nothing about the realm changes.

Whichever shape you pick, the platform integration gives you the same guarantees, none of which you write:

  • Hibernation that’s invisible. The socket survives the DO sleeping; on wake the handshake and any realm resume by patch replay, not a re-download. A realm’s status stays live through a wake.
  • Persistence by default (for a durable realm). Every commit lands in the DO’s SQLite patch log; snapshots are written on a cadence; a cold start is snapshot + tail replay. A changed schema hash refuses to boot unless you pass a migrate hook.
  • Identity + TOFU pins in DO storage, so they survive hibernation — see Identity & Trust.

None of this is Cloudflare-locked. createRealmServerEngine + createRealmAcceptor (realm) and serveChannel (actions) are host-agnostic — anything that can register a WebSocket serves them. See Serving a Realm → outside Cloudflare and Serving & Connecting for Bun / Node / Hono.