Compute at the Edge
Wrangler & the dev loop
Lesson 2 of 5
What you'll learn
- Read a
wranglerconfig file: name, entry point, compatibility date - Run the local dev loop and split config across environments
- Keep plain config in
varsand credentials in secrets — and receive both throughenv
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.
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.
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.