ericrisco/rsc-harness/cloudflare
- community
Checking that the SKILL.md file is still in the repository.
Use when working on Cloudflare's edge platform — wrangler.jsonc bindings, choosing between D1/KV/R2/Durable Objects/Queues, deploying a Worker or SPA via Static Assets, or designing around a Workers runtime limit. NOT generic CI/release (that is `deployment`), NOT Next.js framework wiring (that is `nextjs`), NOT DNS records (that is `domains-dns`).
Install
npx vskill@latest install ericrisco/rsc-harness/cloudflareSKILL.md
Cloudflare Workers & edge primitives
The model in one paragraph
A Worker is a fetch handler that runs at the edge. Everything else — R2, D1, KV, Queues, static assets, Durable Objects — is a binding declared in wrangler.jsonc and reached through env. If a resource is not bound, it is not reachable from your code. There is no connection string and no import of the bucket; you wire it in config, type it on Env, and call env.BINDING. Hold this picture and most "how do I access X" questions answer themselves: declare the binding, redeploy, use env.
Quick start
npm create cloudflare@latest (the C3 scaffolder) bootstraps a Worker or a full framework. Use it — it pins a correct compatibility_date and generates types.
Wrangler is v4 (an incremental release over the v3 rewrite — same config model, updated deps). Pin it: npx wrangler@4.
wrangler.jsonc anatomy
Config may be wrangler.toml, wrangler.json, or wrangler.jsonc. Prefer jsonc so you can comment bindings. Minimum keys: name, main, compatibility_date.
Named environments inherit top-level config and override per env.<name>. See references/wrangler-config.md for the full annotated config, routes, custom domains, and compatibility flags.
Pick the right storage primitive
This is the decision that shapes the architecture. Pick by access pattern and consistency, not by familiarity.
| Primitive | Use for | Consistency | Hard limit | Don't use for | |
|---|---|---|---|---|---|
| D1 | Relational app data, per-tenant DBs | Strong (single SQLite) | 10 GB per database | A single >10 GB monolith; Postgres features (it is SQLite) | |
| KV | Read-heavy config, cached lookups, feature flags | Eventual (~60s to propagate globally) | 25 MiB per value | Counters, sessions you read-after-write, anything strongly consistent | |
| R2 | Files, blobs, uploads, backups | Strong on object | Object storage; no egress fees | Querying/indexing structured data | |
| Durable Objects | Strongly-consistent coordination, per-entity state, WebSockets | Strong (single-threaded per object) | One object = one serialized actor | Bulk storage; high-fanout reads | |
| Queues | Async/batch work, decoupling, retries | At-least-once delivery | Batch ≤100 (default 10) | Synchronous request/response |
Rule of thumb: need read-after-write? Not KV. Need SQL joins? D1. Need a file? R2. Need a counter or lock? Durable Object. Per-primitive binding config and code, consistency semantics, the complete limits/pricing tables, and Hyperdrive for external Postgres are in references/storage-primitives.md.
Static & full-stack hosting
Workers Static Assets is the recommended way to host SPAs and full-stack apps. The Worker and the assets deploy together.
assets.directory— your build output, e.g../dist.assets.binding: "ASSETS"— lets the Worker serve files viaenv.ASSETS.fetch(request).assets.not_found_handling—"single-page-application"(serveindex.htmlon miss, for client-side routing) or"404-page".assets.run_worker_first— run the Worker before serving static assets, e.g. so/api/*hits your handler not a file.
Do not use Workers Sites for new projects — it is deprecated in Wrangler v4 and unsupported by the Cloudflare Vite plugin. Migrating off Pages? Pages still works, but new full-stack work targets Workers; the asset-routing rules and the migration checklist are in references/wrangler-config.md.
Bindings in code
Type every binding on Env. Why: without the interface you lose autocompletion and ship undefined binding bugs to the edge.
Secrets, env vars, local dev
- Secrets via
wrangler secret putonly. Why:varsinwrangler.jsoncis committed plaintext. .dev.varssupplies secrets forwrangler dev; add it to.gitignore.varsblock = non-secret config (API base URLs, feature flags).wrangler devemulates bindings locally; add--remoteto run against real edge resources.
Queues wiring
Producer and consumer are both bindings/handlers — same Worker or different Workers.
Defaults: max_batch_size 10 (max 100), max_retries 3, plus max_batch_timeout. Route exhausted messages to a dead_letter_queue. Make consumers idempotent — at-least-once means a message can arrive twice.
Limits that reshape your design
These numbers are architecture inputs, not trivia. Read them before you design.
- Subrequests per request are capped — fan-out to dozens of origins fails. Batch, cache in KV, or move work to a Queue consumer.
- CPU time per request is bounded (raised on the paid plan). Long CPU work → Queue + consumer, or Durable Object alarms.
- KV value ≤ 25 MiB and eventually consistent — large or write-hot data belongs in R2 or D1.
- D1 ≤ 10 GB per database — shard per tenant/user (D1 is built for many small DBs), don't grow one monolith.
- Queue batch ≤ 100 — size
max_batch_sizeto your downstream throughput, not the max.
Plan note: the Workers Paid plan is a $5/mo minimum bundling Workers, Pages Functions, KV, Hyperdrive, and Durable Objects; a Free plan exists with reduced limits (D1 free-tier limits enforced since 2025-02-10).
Anti-patterns
| Anti-pattern | Why it bites | Do instead | |
|---|---|---|---|
| KV for sessions / counters you read after writing | Eventual consistency: a read after a write can be stale up to ~60s | D1 (strong) or a Durable Object (per-entity strong) | |
| Growing one D1 database past 10 GB | Hard cap; you hit a wall mid-scale | Shard per tenant/user; large blobs go to R2 | |
Omitting compatibility_date | Runtime/flag behavior drifts; deploys become non-reproducible | Set it to today's date at project start; bump deliberately | |
| Avoiding R2 over egress cost | R2 has no egress charges — you're optimizing a cost that doesn't exist | Use R2 for files/blobs; pay only storage + ops | |
| Workers Sites for a new SPA | Deprecated in Wrangler v4; unsupported by the Vite plugin | assets (Static Assets) with not_found_handling | |
Secrets in vars or committed | Plaintext in repo / config = leak | wrangler secret put; .dev.vars (gitignored) for local | |
| Treating D1 like a pooled SQL connection | D1 is accessed over HTTP, not a persistent pool — no transactions across requests, no long-held connections | One prepared statement per call; batch with db.batch() | |
| Heavy fan-out to many subrequests | Hits the subrequest cap and fails the request | Cache in KV, batch, or offload to a Queue consumer |
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/cloudflare/SKILL.md
Popularity
- Repository stars
- 141
- Repository forks
- 11
- 7-day trend score
- 30
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/ericrisco/rsc-harness/cloudflare)