Skip to content

Hosting on Cloudflare

Three ways to host nice-code in a Durable Object (actions, realm-only, or both on one socket) and the serve call for each.

nice-code is built for the edge, and a Cloudflare Durable Object (DO) suits it well: one addressable object per match, room or document, with hibernatable WebSockets, SQLite, and alarms. One serve… call sets up the transport: the secure socket, the crypto identity and TOFU pins in DO storage, recovery after hibernation, and the keepalive. Your DO forwards its four socket events to it.

There are three shapes, depending on whether your object hosts actions, a realm, or both. Pick your row and follow its 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. The DO imports @nice-code/wire and @nice-code/realm and nothing else, with no ActionRuntime and no channel, which mirrors a createWireClient browser client. To add actions later, switch the serve call to the action host and register the same realms.protocol on it. Nothing about the realm changes.

Whichever shape you pick, the platform integration gives you the same guarantees with no code from you:

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

None of this is tied to Cloudflare. createRealmServerEngine with createRealmAcceptor (realm) and serveChannel (actions) are host-agnostic, so anything that can register a WebSocket can serve them. See Serving a Realm → outside Cloudflare and Serving & Connecting for Bun / Node / Hono.