Generated banner for Workers Best Practices
Generated logo for Workers Best Practices

Workers Best Practices

CloudflareOfficialPublished by Cloudflare

  • Skill
  • Guidelines
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

Cloudflare Workers best practices for production applications. Use when writing, reviewing, or configuring Workers.
— the description by Cloudflare

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides best practices for developing and maintaining Cloudflare Workers. It emphasizes using project-specific configurations, generated types, and current documentation to ensure code aligns with the runtime environment. It covers configuration management, observability, platform API usage, and common anti-patterns to avoid during development and code reviews.

What it does

  • Provides guidance on maintaining compatibility dates and enabling observability features.
  • Outlines patterns for secure secret management and environment variable usage.
  • Identifies common coding anti-patterns and suggests preferred implementation alternatives.
  • Advises on correct binding access patterns for module handlers and platform classes.
  • Recommends using generated types to ensure consistency between configuration and code.
  • Offers references for runtime patterns, platform APIs, and configuration settings.

When to use it

  • When writing new Cloudflare Workers code.
  • During code reviews to identify potential configuration or runtime issues.
  • When configuring project settings or updating compatibility dates.
  • When troubleshooting runtime behavior or binding access errors.

Advantages

  • Promotes consistency between Wrangler configuration and application code.
  • Helps prevent common runtime errors related to binding access and serialization.
  • Encourages the use of modern, supported platform APIs and patterns.
  • Reduces the risk of credential leakage through proper secret handling.

Usage examples

“How should I handle environment variables and secrets in my Worker?”
The skill advises using wrangler secret for sensitive data and vars for non-secret configuration, while warning against hardcoding secrets in source or config files.
“What is the best way to define my Env interface?”
The skill recommends running wrangler types to generate the interface automatically, rather than hand-writing it, to ensure it stays in sync with the configuration.
“I am getting an error accessing a binding inside a class. What is wrong?”
The skill explains that platform classes should access bindings via this.env.X, whereas module export handlers should access them via the env parameter.
“How do I enable logging for my Worker?”
The skill provides instructions to enable Workers Logs and Traces by setting observability.enabled and observability.traces.enabled to true in the configuration.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/cloudflare/workers-best-practices/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip workers-best-practices.zip -d .agents/skills

Documentation by Cloudflare

Your knowledge of Cloudflare Workers APIs, types, and configuration may be outdated. Prefer retrieval over pre-training when writing or reviewing Workers code.

Use the project's installed versions, generated types, and Wrangler compatibility settings as the baseline for existing code. Retrieve relevant Cloudflare documentation to verify API, configuration, runtime behavior, and limit claims.

References

Read the sections relevant to the task:

ReferenceWhen to use it
Configuration and observabilityCompatibility dates, bindings, generated types, secrets, logs, and traces
Runtime patternsStreaming, promise lifetime, request state, service calls, security, and runtime tests
Platform API checksHandler signatures, platform classes, binding access, and serialization

For missing evidence, consult Workers best practices or find the affected product in the Cloudflare docs directory. Use the installed Wrangler schema for config fields. A newer type package does not supersede the project's configured target.

Keep Compatibility Dates Current

Use today's date for new Workers. Encourage periodic updates for existing Workers, reviewing compatibility changes and running relevant tests. Assess existing behavior against its configured date and flags; see compatibility guidance.

Enable Observability

Enable Workers Logs and Traces when creating or preparing a Worker for production. Set observability.enabled and observability.traces.enabled to true; the top-level setting alone does not enable traces. Use structured JSON logging and configure sampling for the workload. During reviews, flag missing logs or traces. See the configuration example.

Place Compute Near Regional Databases

For Workers that make multiple sequential queries to one regional database, configure explicit placement matching the database's provider and region before deployment. Ask for missing location information, preserve existing placement choices, and verify handler eligibility and deployed request duration. See database placement.

Anti-Patterns to Flag

Anti-patternConsequence and preferred pattern
await response.text() or similar buffering on unbounded dataCan exhaust Worker memory; stream large or unbounded bodies.
Hardcoded secrets in source or configLeaks credentials through version control; use Wrangler secrets.
Math.random() for security-sensitive tokens or IDsPredictable values; use crypto.randomUUID() or crypto.getRandomValues().
Async work started without awaiting, returning, or attaching it to ctx.waitUntil()Work can be dropped and errors missed; tie it to the request or background-work lifetime.
Module-level mutable request stateLeaks data across requests and can cause I/O ownership errors; pass request state explicitly.
Cloudflare REST API calls for operations available through Worker bindingsAdds network and authentication overhead; use the available binding.
ctx.passThroughOnException() used as general error handlingCan conceal Worker failures by forwarding to the origin; use explicit error handling and structured error responses.
Hand-written Env that duplicates Wrangler bindingsCan drift from configuration; generate binding types with wrangler types.
Direct string comparison of secret valuesCan expose timing differences; use the Web Crypto comparison pattern.
Destructuring ctx methods, such as const { waitUntil } = ctxLoses the receiver; call ctx.waitUntil(...).
any on Env or handler parametersHides binding and handler contract errors; use the project's generated and platform types.
as unknown as T to force a platform type matchHides incompatibilities; fix the underlying contract.
implements used in place of extending a platform base classDoes not inherit runtime behavior, this.ctx, or this.env; use the appropriate base class.
Unbound env.X in a platform class methodBindings are available through this.env.X; see binding access patterns.
Applying one serialization rule across Queues, Workflow steps, storage, and WebSocketsCan reject valid payloads or accept unsupported ones; check the specific API and encoding.

Validation

Use the project's existing checks for affected Workers behavior: type-check binding or handler contract changes, and run relevant runtime tests for behavior changes. Preserve required repository checks; a narrow edit does not require a full Workers audit.

Scope

This skill covers Workers-specific best practices and code review. For related topics:

  • Durable Objects: load the durable-objects skill

  • Workflows: see Rules of Workflows

  • CLI commands: load the cf-cli skill, or the wrangler skill in a project with a Wrangler configuration file

Skill feedback

If the user reports that this skill gave incorrect or outdated guidance, or is missing information, read references/skill-feedback.md.

Files

references/configuration.md

Workers Configuration and Observability

Use the project's Wrangler configuration and installed node_modules/wrangler/config-schema.json to check fields and binding declarations. Consult current product docs when a field or compatibility requirement needs verification. Doc paths below are relative to https://developers.cloudflare.com.

  • Configuration: compatibility dates, Node.js compatibility, generated types, secrets, and config format

  • Binding consistency: configuration and code agree

  • Observability: enable logs and traces, configure sampling, and emit structured logs

Configuration

Keep compatibility_date current

Set compatibility_date to today on new projects. Encourage periodic updates on existing projects to adopt new runtime behavior and fixes. Review the intervening compatibility changes and run relevant tests when advancing the date.

Check: compatibility_date exists and supports the affected feature with the configured flags. Recommend updates as maintenance; flag a compatibility defect when the configured date or flags do not support the required behavior.

// wrangler.jsonc
{
  "compatibility_date": "$today",  // Replace with today's date (YYYY-MM-DD)
  "compatibility_flags": ["nodejs_compat"]
}

Retrieve: current compatibility dates at /workers/configuration/compatibility-dates/.

Enable nodejs_compat

The nodejs_compat flag enables Node.js built-in modules (node:crypto, node:buffer, node:stream). Many libraries require it. Missing this flag causes cryptic import errors at runtime.

Check: compatibility_flags includes "nodejs_compat".

{
  "compatibility_flags": ["nodejs_compat"]
}
Generate binding types with wrangler types

Never hand-write the Env interface. Run wrangler types to generate it from the wrangler config. Re-run after adding or renaming any binding.

Check: no manually defined Env or interface Env that duplicates wrangler config bindings. Look for satisfies ExportedHandler<Env> pattern on the default export.

// Generated by wrangler types — always matches actual config
export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const value = await env.MY_KV.get("key");
    return new Response(value);
  },
} satisfies ExportedHandler<Env>;

Anti-pattern:

// Hand-written Env that drifts from actual bindings
interface Env {
  MY_KV: KVNamespace;  // What if the binding name changed?
}
Store secrets with wrangler secret

Secrets must never appear in wrangler config or source code. Use wrangler secret put and access via env at runtime. Non-secret config goes in vars.

Check: no string literals that look like API keys, tokens, or credentials. Verify .env is in .gitignore for local dev.

{
  "vars": {
    "API_BASE_URL": "https://api.example.com"  // Non-secret: OK in config
  }
  // Secrets set via: wrangler secret put API_KEY
}

Anti-pattern:

{
  "vars": {
    "API_KEY": "sk-live-abc123..."  // Secret in version control
  }
}
Use wrangler.jsonc for config

Prefer wrangler.jsonc over wrangler.toml. Newer features are JSON-only. JSONC supports comments for documenting config decisions.

Check: project uses wrangler.jsonc (or wrangler.json). Flag wrangler.toml in new projects.


Binding-code consistency

For executable Worker examples, verify name, compatibility_date, and main against the target Wrangler schema.

  1. Every env.X reference in code has a corresponding binding declaration in config

  2. Names match exactly (case-sensitive)

  3. For Durable Objects: class_name matches the exported class name

An unused binding alone is not a finding; establish a concrete configuration or runtime consequence before recommending a change.

For a new Durable Object class, verify its migration entry and exported class name against the target Wrangler schema.

Place compute near regional databases

Hyperdrive connection pooling does not automatically place a Worker near its database. For multiple sequential queries to one regional database, identify the actual provider and region and configure an explicit region hint before deployment. Preserve explicit user placement choices and ask for missing region information rather than guessing from a connection hostname.

Retrieve Workers placement for supported options and handler limitations. Use CF's configuration mapping for cloudflare.config.ts, or the installed schema for Wrangler projects. Placement affects fetch handlers, not RPC methods or named entrypoints. For unknown or multiple back-end locations, consider Smart Placement with its traffic requirements. Compare request duration on deployed Workers using representative queries and cache behavior; local development does not measure production placement.

Observability

Enable Workers Logs and Traces

Enable Workers Logs and Traces in Wrangler config before deploying to production. Set observability.enabled and observability.traces.enabled to true; the top-level setting alone does not enable traces. Use head_sampling_rate to control volume and cost. Use structured JSON logging — console.log(JSON.stringify({...})) — so logs are searchable. Use console.error for errors (appears at error severity in the dashboard).

Check: logs and traces are enabled in the target deployment environment, with neither disabled by an environment override. Check observability.enabled, observability.logs.enabled, and observability.traces.enabled, accounting for their defaults. Logging uses structured JSON, not string concatenation.

{
  "observability": {
    "enabled": true,
    "logs": { "enabled": true, "head_sampling_rate": 1 },
    "traces": { "enabled": true, "head_sampling_rate": 0.01 }
  }
}
// Structured JSON — searchable and filterable
console.log(JSON.stringify({ message: "incoming request", method: request.method, path: url.pathname }));

// Error severity
console.error(JSON.stringify({ message: "request failed", error: e instanceof Error ? e.message : String(e) }));

Anti-pattern:

// Unstructured string logs — hard to query
console.log("Got a request to " + url.pathname);

Retrieve: Workers Logs and Traces for current config options.

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
Cloudflare
Publisher
Cloudflare (Official)
Source
cloudflare/skills · skills/workers-best-practices · commit 6eb6c78
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by Cloudflare or Cloudflare.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download workers-best-practices.zip