Cloudflare Durable Objects for stateful coordination and real-time apps. Use for chat, multiplayer games, WebSocket hibernation, or encountering class export, migration, alarm errors.
Installs just this skill. Get the whole plugin for auto-invocation.
โก How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/cloudflare-durable-objects
๐๏ธ Context preview
The summary Claude sees to decide when to auto-load this skill.
Cloudflare Durable Objects for stateful coordination and real-time apps. Use for chat, multiplayer games, WebSocket hibernation, or encountering class export, migration, alarm errors.
๐ Stats
Stars194
Forks29
LanguageTypeScript
LicenseMIT
๐ฆ Ships with claude-skills
</> SKILL.md
cloudflare-durable-objects.SKILL.md
---name: cloudflare-durable-objects
description: "Cloudflare Durable Objects for stateful coordination and real-time apps. Use for chat, multiplayer games, WebSocket hibernation, or encountering class export, migration, alarm errors."
metadata:
keywords:
- durable objects
- cloudflare do
- DurableObject class
- do bindings
- websocket hibernation
- do state api
- ctx.storage.sql
- ctx.acceptWebSocket
- webSocketMessage
- alarm() handler
- storage.setAlarm
- idFromName
- newUniqueId
- getByName
- DurableObjectStub
- serializeAttachment
- real-time cloudflare
- multiplayer cloudflare
- chat room workers
- coordination cloudflare
- stateful workers
- new_sqlite_classes
- do migrations
- location hints
- RPC methods
- blockConcurrencyWhile
- "\"do class export\""
- "\"new_sqlite_classes\""
- "\"migrations required\""
this.sql.exec('CREATE TABLE IF NOT EXISTS counts (key TEXT PRIMARY KEY, value INTEGER)');
}
async increment(): Promise<number> {
this.sql.exec('INSERT OR REPLACE INTO counts (key, value) VALUES (?, ?)', 'count', 1);
return this.sql.exec('SELECT value FROM counts WHERE key = ?', 'count').one<{value: number}>().value;
}
}
```
**Load `references/state-api-reference.md` for complete SQL and KV API documentation, cursor operations, transactions, parameterized queries, storage limits, and migration patterns.**
---
## WebSocket Hibernation API
Handle **thousands of WebSocket connections** per DO instance with automatic hibernation when idle (~10s no activity), saving duration costs. Connections stay open at the edge while DO sleeps.
**CRITICAL Rules**:
- โ Use `ctx.acceptWebSocket(server)` (enables hibernation)
- โ Use `ws.serializeAttachment(data)` to persist metadata across hibernation
- โ Restore connections in constructor with `ctx.getWebSockets()`
- โ Don't use `ws.accept()` (standard API, no hibernation)
- โ Don't use `setTimeout`/`setInterval` (prevents hibernation)
- Best-effort (not guaranteed), only affects first creation
**Data residency with jurisdiction restrictions:**
- Use `newUniqueId({ jurisdiction: 'eu' })` or `{ jurisdiction: 'fedramp' }`
- Strictly enforced (DO never leaves jurisdiction)
- Cannot combine with location hints
- Required for GDPR/FedRAMP compliance
**Load `references/stubs-routing.md` for complete guide to ID methods, stub management, location hints, jurisdiction restrictions, use cases, best practices, and error handling patterns.**
---
## Migrations - Managing DO Classes
**Migrations are REQUIRED** when creating, renaming, deleting, or transferring DO classes between Workers.
**Four migration types:**
1. **Create New DO**: Use `new_sqlite_classes` (recommended, 1GB) or `new_classes` (legacy KV, 128MB)
2. **Rename DO**: Use `renamed_classes` with `from`/`to` mapping (data preserved, bindings forward)
3. **Delete DO**: Use `deleted_classes` (โ ๏ธ immediate deletion, cannot undo, all storage lost)
4. **Transfer DO**: Use `transferred_classes` with `from_script` (moves instances to new Worker)
**Load `references/common-patterns.md` for complete implementations of all 4 patterns with full code examples, SQL schemas, alarm usage, error handling, and best practices.**
---
## Critical Rules
**โ Always:**
- Export DO class: `export default MyDO`
- Call `super(ctx, env)` first in constructor
- Use `new_sqlite_classes` in migrations (1GB vs 128MB KV)
- Use `ctx.acceptWebSocket()` for hibernation (not `ws.accept()`)
- Persist state to storage (not just memory)
- Use alarms instead of setTimeout/setInterval
- Use parameterized SQL: `sql.exec('... WHERE id = ?', id)`
- Minimize constructor work, use `blockConcurrencyWhile()`
**โ Never:**
- Create DO without migration (error)
- Forget to export class (binding not found)
- Use setTimeout/setInterval (prevents hibernation)
- Rely only on in-memory state for WebSockets (use serializeAttachment)
- Deploy migrations gradually (migrations are atomic)
- Enable SQLite on existing KV-backed DO (must create new class)
- Assume location hints are guaranteed (best-effort only)
---
## Known Issues Prevention
This skill prevents **15+ documented issues**. Top 3 most critical:
### Issue #1: Class Not Exported
**Error**: `"binding not found"` | **Why**: DO class not exported
**Fix**: `export default MyDO;`
### Issue #2: Missing Migration
**Error**: `"migrations required"` | **Why**: Created DO without migration entry
**Fix**: Add `{ "tag": "v1", "new_sqlite_classes": ["MyDO"] }` to migrations
### Issue #3: setTimeout Breaks Hibernation
**Error**: DO never hibernates, high charges | **Why**: `setTimeout` prevents hibernation
**Fix**: Use `await ctx.storage.setAlarm(Date.now() + 1000)` instead
**12 more issues covered**: Wrong migration type, constructor overhead, in-memory state lost, outgoing WebSocket no hibernation, global uniqueness confusion, partial deleteAll, binding mismatch, state size exceeded, migration not atomic, location hint ignored, alarm retry failures, fetch blocks hibernation.
**Load `references/top-errors.md` for complete error catalog with all 15+ issues, detailed prevention strategies, debugging steps, and resolution patterns.**
---
## Configuration & TypeScript
Configure wrangler.jsonc with DO bindings and migrations, set up TypeScript types with proper exports.
**Load `references/typescript-config.md` for**: wrangler.jsonc structure, TypeScript types, Env interface, tsconfig.json, common type issues