Chapter 12 · Workers Best Practices
Subchapter 12.1
references/review.mdMarkdown8 KBView on GitHub
How to review Workers code for type correctness, API usage, config validity, and best practices. This is self-contained — do not assume access to other skills.
Prefer retrieval over pre-training. Types, config schemas, and APIs change with compatibility dates and new bindings.
Fetch the latest @cloudflare/workers-types before reviewing. The project may have an older version installed.
mkdir -p /tmp/workers-types-latest && \
npm pack @cloudflare/workers-types --pack-destination /tmp/workers-types-latest && \
tar -xzf /tmp/workers-types-latest/cloudflare-workers-types-*.tgz -C /tmp/workers-types-latest
# Types are at /tmp/workers-types-latest/package/index.d.tsSearch this file for the specific type, class, or interface under review. Do not guess type names.
Alternative: npx wrangler types generates a typed Env interface from the local wrangler config.
Fallback: read node_modules/@cloudflare/workers-types/index.d.ts. Note the installed version.
The authoritative schema is bundled with wrangler as config-schema.json (JSON Schema draft-07).
# Read from local node_modules
cat node_modules/wrangler/config-schema.jsonDo not guess field names or structures — look them up.
Use the Cloudflare docs search tool if available, or fetch from https://developers.cloudflare.com/workers/. The best practices page lives at /workers/best-practices/workers-best-practices/.
any, unknown, object, or Record<string, unknown> on bindings.wrangler types over hand-written interfaces.Verify against current type definitions — do not assume signatures are stable.
"cloudflare:workers")DurableObject<Env>)env.X in module export handlers, this.env.X in classes extending platform base classesExecutionContext as the third param in module export handlers (needed for ctx.waitUntil())fetch() handlers must return Promise<Response>fetch, scheduled, queue, email): bindings via env.X parameterWorkerEntrypoint, DurableObject, Workflow, Agent): bindings via this.env.XFlag env.X inside a class extending a platform base class. Flag this.env.X inside a module export handler.
| Rule | Detail |
|---|---|
No any | Never on binding types, handler params, or API responses |
| No double-casting | as unknown as T hides real incompatibilities — fix the underlying design |
| Justify suppressions | @ts-ignore/@ts-expect-error must include a comment explaining why |
Prefer satisfies | Use satisfies ExportedHandler<Env> over as — validates without widening |
| Validate, do not assert | Schema or type guard for untyped data (JSON, parsed bodies), not as |
Old patterns survive in codebases long after APIs change.
extends vs implements: platform classes use extends, not implements. The implements pattern is legacy and loses this.ctx, this.env."cloudflare:workers" vs "cloudflare:workflows".this.state to this.ctx in Durable Objects. Search types to confirm.For executable examples, verify: name, compatibility_date, main. Check the schema for current required fields.
wrangler.jsonc) — preferred for new projectswrangler.json) — valid but no commentswrangler.toml) — legacy; acceptable in existing content, flag in new projectsenv.X reference in code has a corresponding binding declaration in configclass_name matches the exported class name| Check | What to look for |
|---|---|
Stale compatibility_date | Should be recent; use $today placeholder in docs |
| Missing DO migrations | Every new DO class needs a migration entry |
| Binding name mismatch | Config binding/name must match env.X in code |
| Secrets in config | Never in vars — use wrangler secret put |
| Wrong binding key | Verify top-level key name against the schema |
| Missing entrypoint | main required for executable Workers |
See the full anti-patterns table in SKILL.md. The type-specific ones to watch for during review:
any on Env or handler params — defeats type safety for all downstream binding accessas unknown as T — hides real type incompatibilities; fix the underlying design@ts-ignore/@ts-expect-error without explanation — masks errors silently; require a justifying commentimplements instead of extends on platform base classes — legacy pattern; loses this.ctx, this.envenv.X inside class body — should be this.env.X in platform base classesthis.env.X in module export handler — should be env.X parameterResponse, Error in step/queue compiles but fails at runtimeData crossing these boundaries must be structured-clone serializable:
.send() or .sendBatch()storage.put() or SQLpostMessage(): WebSocket messagesNon-serializable types to flag: Response, Request, Error, functions, class instances with methods, Map/Set, Symbol.
Valid: plain objects, arrays, strings, numbers, booleans, null, ArrayBuffer, Date.
any, no unsafe castsnpx tsc --noEmit, lint for no-floating-promises**[SEVERITY]** Brief description
`file.ts:42` — explanation with evidence
Suggested fix: `code`Severity: CRITICAL (security, data loss, crash) | HIGH (type error, wrong API, broken config) | MEDIUM (missing validation, edge case) | LOW (style, minor improvement)