🏠 HÖMSTYLE · E-commerce

Collaborative Room Designer

Place HÖMSTYLE furniture in a live 2D floor plan or 3D view. Every move syncs to all connected browsers in real time — no backend, no database, no load balancer. One Durable Object per room, SQLite for state, WebSocket Hibernation for zero idle cost.

The Problem

""We want a room planner on our product pages — customers return sofas because they can't visualise the fit. But our team scoped it as a 6-month project: real-time database, WebSocket server, Socket.io cluster, load balancer, Redis for pub/sub. We can't justify that for a planner.""

The Outcome

1 file

One Durable Object class handles WebSocket upgrades, SQLite furniture state, live cursors, and multi-user sync. No Redis. No Socket.io. No load balancer. 1,000 idle connections cost $0/month — the DO hibernates and wakes in under 5 ms.

Live demo below
Loading Room Designer...

Productionising this

What changes when you ship this for real

Hibernation = $0 idle

Use state.acceptWebSocket() (Hibernation API), NOT server.accept(). Hibernating sockets bill ~$0; active sockets bill duration. The /demo/room-designer DO uses Hibernation correctly.

SQLite size limits

Per-DO SQLite has a 10 GB cap. For furniture rooms this is fine; for chat or telemetry, partition by day/user/region across multiple DO instances.

Migrations

DO classes need explicit migrations in wrangler.toml — new_classes, new_sqlite_classes, deleted_classes. The room-designer DO has v-room-1 → v-room-2 migration as a worked example.

Backups

SQLite in DO is durable but not snapshotted by Cloudflare. For audit/compliance, periodically dump to R2 via storage.list() + serialise.

Auth

Don't leak roomId in URLs without auth. Sign room access tokens (JWT or KV-stored short-lived) so a stranger can't connect to vardagsrum just by guessing the path.

Observability

Each DO instance is a separate trace in Workers Logs. Tag log lines with roomId + doVersion so you can replay a specific room's history when debugging.