BuildBot

Compute at the Edge

Wrangler & the dev loop

Lesson 2 of 5

What you'll learn

  • Read a wrangler config file: name, entry point, compatibility date
  • Run the local dev loop and split config across environments
  • Keep plain config in vars and credentials in secrets — and receive both through env

Wrangler is the Workers CLI. npm create cloudflare@latest scaffolds a project; the file that defines it is wrangler.toml (or wrangler.jsonc — same schema, newer default). Three fields matter from day one:

name = "edge-notes"                 # the Worker's name on Cloudflare
main = "src/index.js"               # the module with your fetch handler
compatibility_date = "2026-07-01"   # pins runtime behavior so updates can't break you

[vars]
APP_NAME = "Edge Notes"             # plain, non-secret config

npx wrangler dev starts the dev loop. It runs your Worker locally in workerd — the same open-source runtime Cloudflare runs in production — with hot reload on save. Add --remote to run on Cloudflare's actual network instead when you need real-world behavior.

vars, secrets, and environments

[vars] values are committed to the repo and visible to anyone who can read it — fine for feature flags and app names, never for credentials. Secrets take a different path entirely:

# Nothing secret appears in the config file. Instead:
#   npx wrangler secret put API_KEY     # encrypted, stored on Cloudflare
# and for local dev, a git-ignored .dev.vars file:
#   API_KEY=sk-local-dev-123

[env.staging]
vars = { APP_NAME = "Edge Notes (staging)" }

[env.staging] defines a named environment — a parallel copy of the Worker with its own vars, bindings, and routes. wrangler dev --env staging and wrangler deploy --env staging target it; production stays untouched until you say so.

Bindings: the one door into the platform

Here is the concept the whole platform hangs on. A Worker has no connection strings, no SDK clients, no ambient credentials. Everything it can reach — vars, secrets, KV namespaces, D1 databases, queues, other Workers — is declared in config and injected as a property of env, the second argument to fetch. Declare binding = "CACHE" under kv_namespaces and env.CACHE is a live KV client at runtime. Config declares; the runtime injects; your code just reads env. This makes every dependency explicit, swappable per environment, and trivially fakeable in tests — which is exactly what the challenge does.

Secrets never go in the config file

The classic leak is a credential pasted into [vars] "just to test". vars ship in your repo; secrets live encrypted on Cloudflare (wrangler secret put) and in a git-ignored .dev.vars locally. Both arrive on env identically, so code never knows the difference.

Model the bindings injection

Run it. buildEnv plays wrangler's role: it assembles env from declared vars, out-of-band secrets, and a stub KV binding, then the Worker reads everything through env. Try moving API_KEY into config.vars and notice the code cannot tell — that is the point of the one-door design.

Loading editor…
Knowledge check

Where should a third-party API key live in a Workers project?

Next: your first two bindings that actually store things — KV for global reads, and the Cache API for free.

Saved on this device. Sign in to sync your progress everywhere.