Cloudflare Workers · D1 · KV · R2 · Durable Objects
Production-Ready
Cloudflare Workers
Scaffold Generator
D1, KV, R2, Durable Objects, auth middleware, ADRs, threat model, and test plan from day one. Not a starter template — a governed production foundation.
The problem with Cloudflare starters
The official starter gives you a hello-world. Production needs something else.
Most Cloudflare Workers starters do one thing: get something responding at the edge. That's fine for a proof of concept. When you're building a real SaaS — multi-tenant D1 data, session auth, R2 asset storage, Durable Objects for stateful coordination — the starter drops you off at the hello-world cliff.
The wrangler.toml is wrong. D1 binding types aren't declared, so your Env interface is untyped and your queries will fail silently in workers that hit an unprepared binding. KV operations run sync-style in contexts that block the event loop. Secrets end up hardcoded into source because nobody set up the wrangler secret workflow. Durable Objects run without any concurrency guards, so burst load creates hotspot failures that don't reproduce in local dev.
And none of it is documented. There's no record of why you chose D1 over KV for relational data, no threat model covering the Cloudflare-specific attack surface, no test plan that covers what happens when a DO request queue overflows. The next developer — or the next AI agent — has no idea what constraints were intentional.
The Cloudflare platform is genuinely excellent. The starter ecosystem hasn't caught up to production requirements. Stackbilder does.
Cloudflare Workers is the only stack fully supported today. Generate your governed scaffold, deploy with confidence.
Common Workers mistakes the scaffold prevents
Missing binding types in wrangler.toml
Env interface is untyped; TypeScript won't catch binding access errors at compile time.
Sync D1 queries in async handlers
D1 is async by design. Sync-style access patterns lock up the event loop and cause timeout cascades.
Missing Cache-Control on R2 responses
Assets served directly from R2 without cache headers saturate R2 read credits and bypass the CDN layer.
Secrets in source control
API keys and service secrets committed to wrangler.toml instead of set via wrangler secret put.
DO hotspot under load
Single Durable Object instance handling all concurrent requests without queuing — fails under burst.
No auth middleware — route-level guards
Auth checked inside route handlers instead of at the middleware layer lets certain request paths bypass it.
What Stackbilder generates
Bindings, governance, and test coverage. All of it in under 20ms.
wrangler.toml + Typed Bindings
A complete wrangler.toml with correct binding declarations for every service you're
using. The Env interface is fully typed. Secrets declared via the
vars pattern are flagged
and redirected to wrangler secret put.
Service bindings to external workers are stubbed with type-safe fetch wrappers.
D1 database IDs, KV namespace IDs, and R2 bucket names are documented as
environment-specific — the scaffold tells you exactly what to fill in per environment.
binding = "DB"
database_name = "app-prod"
database_id = "# fill via wrangler d1 create"
[[kv_namespaces]]
binding = "SESSION"
id = "# fill via wrangler kv:namespace create"
[[r2_buckets]]
binding = "ASSETS"
bucket_name = "app-assets-prod"
Edge-Specific Threat Model
Workers applications have a different threat surface than traditional servers. The scaffold's threat model includes Cloudflare-native vectors that generic security checklists miss: WAF bypass by direct-hitting the worker origin, KV cache poisoning through user-controlled cache keys, D1 injection from untrusted service binding payloads, and Durable Object concurrency race conditions. Each threat includes a severity rating, the attack vector, and a concrete mitigation mapped to the scaffold.
Attacker accesses worker.dev origin directly,
bypassing zone-level WAF rules.
Mitigation: validate X-Custom-Secret header
in worker; block requests without it.
## T-006 KV Cache Poisoning [MEDIUM]
User input used as KV key without normalization
allows key-space squatting across tenants.
Mitigation: prefix all KV keys with tenant_id.
D1 + Auth Architecture ADRs
Architectural decisions documented with context, alternatives, and consequences. The scaffold generates ADRs for the choices that matter most in a Workers app: why D1 over KV for relational data, why session cookies over JWTs in the edge runtime context, how Durable Objects are namespaced for multi-tenant safety, and what the R2 access control model is. Each ADR is linked to the threat items it was written to address.
Status: Accepted
Context: App requires multi-tenant row isolation
and cross-record queries (joins). KV is key-value
only; no query predicates, no transactions.
Decision: D1 (SQLite at the edge) with tenant_id
column on every table. RLS enforced at query layer.
Consequence: Consistent query API. Tenant isolation
verifiable via test_rls test suite. See T-005.
Workers-Specific Test Plan
The test plan is structured around the three layers that matter for a Workers app: unit tests via Vitest + Miniflare (worker logic in isolation), D1 integration tests (schema, migrations, RLS enforcement), and end-to-end scenarios via wrangler dev (auth flow, binding behavior, DO lifecycle). Coverage targets are tiered by concern — auth and data access at 90%+, edge cases at 70%.
test_auth_middleware: rejects missing token
test_do_queue: serializes concurrent requests
test_kv_key_prefix: tenant isolation on reads
## Integration — D1 via wrangler d1 execute
test_rls: tenant_A rows invisible to tenant_B
test_migration: schema idempotent across versions
## E2E — wrangler dev
test_full_auth_flow: login → session → route
test_r2_upload: presigned URL → GET → 200
Example output
A real ADR from a Cloudflare Workers scaffold.
This is what gets generated — not a stub you fill in, an actual decision record with enough context to be useful six months from now.
# ADR-004: Durable Objects Concurrency Strategy
Status: Accepted
Date: 2025-05-24
Threat ref: T-007 (DO hotspot under burst load)
## Context
This app uses a Durable Object per-session for real-time coordination.
Under burst load (> 20 concurrent requests to a single DO), the event queue
saturates and requests time out. The CF runtime serializes DO requests,
so a slow handler blocks every subsequent request to that instance.
## Decision
Adopt a request-scoped DO pattern: one DO instance per user session,
not per global entity. DO name derived from session_id, not user_id.
All handlers implement a 5s internal timeout with graceful degradation.
Queue depth capped at 50; excess returns 429 to the calling worker.
## Alternatives considered
1. Single global DO — rejected: single point of contention at scale.
2. KV for coordination state — rejected: no atomic read-modify-write.
3. External Redis via Hyperdrive — rejected: adds latency hop, over-engineered.
## Consequences
+ DO per session scales horizontally with user count.
+ Burst isolation: one user's traffic spike cannot starve another's DO.
- Eviction logic required: idle sessions must be cleaned up via alarm().
- Test coverage must include concurrent request simulation (see test plan §3).
How it works
Describe your Workers app. Get a production foundation in 20ms.
Describe your intention
"Multi-tenant SaaS with D1, Durable Objects for real-time sync, session-based auth, and R2 for user file storage" is enough. You don't need a full spec — just what you're building.
Deterministic scaffold generation
The TarotScript engine maps your intention to a Workers architecture pattern. It generates wrangler.toml, typed bindings, auth middleware, D1 schema conventions, and the full governance suite in ~20ms. No inference, no hallucinations, same output every time.
Build on a production foundation
Download your scaffold: threat model, ADRs, test plan, and project structure with constraints.yaml. Use it with any Workers-compatible AI tool — or just build against it directly. The governance artifacts travel with your code.
Common questions
What makes a Cloudflare Workers app production-ready?
Correct binding types in wrangler.toml, auth that runs before any route handler, D1 queries that don't block the event loop, secrets outside source control, Durable Object access patterns with concurrency guards, documented architectural decisions, and a threat model covering edge-specific attack vectors. Most Workers starters cover none of these.
Does this generate actual wrangler.toml and binding configuration?
Yes. Complete wrangler.toml with typed D1, KV, R2, and Durable Object binding declarations. The Env interface is generated to match. Secrets are flagged for wrangler secret put rather than committed as vars.
How does the threat model handle edge-specific attack vectors?
It includes WAF bypass via direct worker.dev origin access, KV cache poisoning through user-controlled keys, D1 injection from untrusted worker-to-worker binding calls, and DO hotspot failures under concurrent load. These don't appear in generic OWASP checklists.
Can I use this with existing Workers projects?
Yes. Stackbilder generates governance from architectural intent, not from code. Run it to produce a threat model and ADR baseline, then use them to audit what you've already built. Works as a hardening layer at any point in the project lifecycle.
What's the difference between this and a Workers starter template?
A starter template gives you routing and a hello-world response. This scaffold gives you typed bindings, auth middleware, D1 RLS patterns, an edge-specific threat model, ADRs for every non-obvious decision, and a three-layer test plan. Same time to start, completely different production trajectory.
Related pages
Stop shipping hello-world to production.
Free tier includes 3 scaffolds per month — full governance suite with every one. No credit card.