A ready-to-deploy wrangler.toml
Cloudflare Workers read their entire deploy configuration from wrangler.toml: the entry point, the runtime compatibility date, routes, and resource bindings. Getting the TOML syntax and binding shapes right by hand is error-prone, so this builder generates a valid file from simple inputs.
How it works
The tool writes top-level keys — name, main, optional account_id, and compatibility_date — then appends TOML table arrays for anything you enable. A route becomes a [[routes]] table with a pattern and optional zone_name. KV, R2, and D1 each get their correct array-of-tables form: [[kv_namespaces]] with binding + id, [[r2_buckets]] with binding + bucket_name, and [[d1_databases]] with binding, database_name, and database_id. String values are TOML-quoted and escaped so special characters do not break parsing. An optional [env.staging] block adds a named environment with its own name and a vars table.
What each section of wrangler.toml does
Top-level keys define the Worker itself:
name = "my-worker"
main = "src/index.ts"
compatibility_date = "2024-11-01"
name is how Cloudflare identifies the Worker in your account — it also becomes part of the default *.workers.dev subdomain. main is the entry point file that Wrangler bundles; for TypeScript projects, esbuild handles transpilation automatically. compatibility_date pins the runtime to a specific snapshot of the Workers environment, which prevents unexpected breakage when Cloudflare ships changes to built-in APIs.
Routes map URL patterns to the Worker:
[[routes]]
pattern = "example.com/api/*"
zone_name = "example.com"
Without a route, the Worker is only accessible at its *.workers.dev URL. Adding a route with a pattern makes it serve traffic from your own domain. The zone_name identifies which Cloudflare zone the route belongs to and must match a domain on your account.
KV namespace bindings make a Workers KV store available inside the Worker:
[[kv_namespaces]]
binding = "MY_KV"
id = "abc123..."
At runtime, env.MY_KV.get("key") and .put("key", "value") access the store. The id comes from the Cloudflare dashboard or wrangler kv:namespace list.
R2 bucket bindings give the Worker access to an object storage bucket:
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "my-bucket-name"
At runtime, env.MY_BUCKET.get(key) returns an object and .put(key, data) writes one. R2 has no egress fees for Worker-to-R2 traffic, making it cost-effective for serving files.
D1 database bindings connect the Worker to a SQLite-compatible serverless database:
[[d1_databases]]
binding = "MY_DB"
database_name = "my-database"
database_id = "xyz789..."
At runtime, env.MY_DB.prepare("SELECT * FROM users").all() executes SQL. D1 is Cloudflare’s edge-native relational database; the binding makes it appear as a typed variable in your Worker code.
The staging environment pattern
[env.staging]
name = "my-worker-staging"
vars = { ENVIRONMENT = "staging" }
This section overrides specific fields for a named deploy target. Run wrangler deploy --env staging to use it; wrangler deploy without a flag uses the base config. A staging environment typically has a different worker name (to avoid overwriting production), different KV namespace IDs pointing at test data, and different environment variables.
Deployment workflow
After copying the generated wrangler.toml into your project root:
- Run
wrangler loginto authenticate (one-time). - Run
wrangler deployto build and push the Worker. - Test at the
*.workers.devURL, then configure a production route and deploy again. - For staging, run
wrangler deploy --env stagingand verify before promoting.