Your First Cloudflare Worker
15 Oct 2026A Cloudflare Worker is a JavaScript (or Rust/Wasm) function that runs on Cloudflare’s edge network instead of a server you manage. No VM to patch, no container to build. You write a function, deploy it, and it runs in hundreds of locations. Here’s a real one, deployed in ten minutes.
1. Install Wrangler
Wrangler is Cloudflare’s CLI for Workers.
npm install -g wrangler
wrangler login
wrangler login opens a browser tab to authorize the CLI against your Cloudflare account.
2. Scaffold a project
npm create cloudflare@latest my-worker -- --type hello-world
cd my-worker
This gives you a minimal src/index.js (or .ts) and a wrangler.toml config file.
3. Write the endpoint
Open src/index.js and replace it with something real — an endpoint that returns JSON based on the request:
export default {
async fetch(request) {
const url = new URL(request.url);
if (url.pathname === "/api/hello") {
return Response.json({
message: "hello from the edge",
colo: request.cf?.colo ?? "unknown",
});
}
return new Response("Not found", { status: 404 });
},
};
request.cf.colo tells you which Cloudflare data center handled the request — useful for confirming it’s actually running at the edge, not just locally.
4. Run it locally
wrangler dev
This starts a local server that emulates the Workers runtime (via workerd, the same engine Cloudflare runs in production — not a Node polyfill). Hit http://localhost:8787/api/hello and confirm you get JSON back.
5. Deploy
wrangler deploy
You’ll get a URL like https://my-worker.<your-subdomain>.workers.dev. That’s live, globally, immediately — no build pipeline, no waiting for a CDN to propagate.
What you don’t get for free
- No filesystem.
fsdoesn’t exist. State goes in KV, D1, R2, or Durable Objects. - CPU time limits. Free tier caps CPU time per request (currently well under a second of actual compute); this is fine for API glue and header logic, not for image processing or heavy loops.
- No persistent in-memory state between requests unless you use a Durable Object — each request may hit a different isolate.
The failure you’ll hit first
Importing a Node-only package:
Error: No such module "node:crypto".
Workers ship a node_compat flag for partial compatibility, but not every package works. Check before you build a feature around a library — search for “workers compatible” or check if it depends on native bindings.
Next step
Bind a KV namespace or D1 database once you need state beyond a single request — plain fetch-and-respond Workers like this one cover routing, auth checks, and header rewrites without touching storage at all.