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 with | Guide |
|---|---|---|
| Actions only (typed RPC, server push) | serveDurableObject — @nice-code/action/platform/cloudflare | Action → Cloudflare |
| A realm only (shared state, no actions) | serveWireDurableObject — @nice-code/wire/platform/cloudflare, with hostRealm registered on it | Serving a Realm |
| Both, on one socket | serveDurableObject 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.
What comes free
Section titled “What comes free”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
statusstayslivethroughout. - 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
migratehook. - Identity and TOFU pins in DO storage, so they survive hibernation. See Identity & Trust.
Beyond Cloudflare
Section titled “Beyond Cloudflare”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.