Overview
A Worker is a fetch handler that Cloudflare runs at its edge. This guide scaffolds one, binds a KV namespace, tests locally, deploys, and verifies. Limits, pricing, and design rules are in cloudflare-workers; KV semantics are in cloudflare-kv.
Prerequisites
- A Cloudflare account. The Free plan allows 100,000 requests per day and 10 ms CPU time per request; paid plans lift the daily cap.
- Node 22 or newer and npm. Install Wrangler in the project, not globally:
npm i -D wrangler@latest(the scaffold does this).
Steps
1. Scaffold
npm create cloudflare@latest -- my-worker
cd my-worker
npx wrangler loginPick the “Hello World” Worker. The scaffold creates wrangler.jsonc (the default config format), src/index.ts, and tsconfig.json.
2. Write the handler
export interface Env { MY_KV: KVNamespace }
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/health") return new Response("ok");
const key = url.searchParams.get("key");
if (!key) return new Response("Missing key", { status: 400 });
const value = await env.MY_KV.get(key);
return value === null ? new Response("Not found", { status: 404 }) : Response.json({ key, value });
},
};3. Bind KV
npx wrangler kv namespace create MY_KV # prints the namespace id{
"name": "my-worker",
"main": "src/index.ts",
"compatibility_date": "2026-10-01",
"kv_namespaces": [{ "binding": "MY_KV", "id": "<id from the command>" }]
}The binding name must equal the property in Env. Keep compatibility_date recent; it pins runtime behavior.
4. Test locally
npx wrangler dev # http://localhost:8787
npx wrangler kv key put --binding=MY_KV hello world
curl "http://localhost:8787/?key=hello"wrangler dev uses a local simulation of KV by default, so it never touches production data. Without --remote on the put, the key goes to the local store; add --remote to write to the real namespace.
5. Deploy
npx wrangler deployFor a custom domain, add "routes": [{ "pattern": "api.example.com", "custom_domain": true }]; the zone must be on Cloudflare. For CI, run npx wrangler deploy with CLOUDFLARE_API_TOKEN stored as a repository secret (github-actions).
Verify it worked
npx wrangler kv key put --binding=MY_KV ping pong --remote
curl -s https://my-worker.<your-subdomain>.workers.dev/health # ok
curl -s "https://my-worker.<your-subdomain>.workers.dev/?key=ping" # {"key":"ping","value":"pong"}
npx wrangler tailCommon errors
No account id found. Setaccount_idinwrangler.jsoncorCLOUDFLARE_ACCOUNT_IDin the environment.- The binding is
undefined. Thebindingname differs from theEnvproperty. - A key written during
wrangler devis missing in production. It went to the local store; write with--remote. - A route does not match. A Custom Domain cannot be created on a hostname that already has a CNAME record.
FAQ
How many requests does the Cloudflare Workers Free plan allow?
The Free plan allows 100,000 requests per day and 10 ms CPU time per request; paid plans lift the daily cap.
Does wrangler dev use my production KV data?
No; wrangler dev uses a local simulation of KV by default. Add --remote to write to the real namespace.
Why is my KV binding undefined in a Worker?
The binding name in wrangler.jsonc differs from the property in Env; they must match exactly.
Should I install Wrangler globally?
No; install it in the project with npm i -D wrangler@latest, which the create-cloudflare scaffold does for you.