---
title: "Cloudflare Workers: fetch handler and local preview"
license: CC0-1.0
license_url: https://creativecommons.org/publicdomain/zero/1.0/
source: https://iinventedlight.com/library/notes/cloudflare-workers-fetch-handler.md
upstream_source: https://developers.cloudflare.com/workers/get-started/guide/
author: "iinventedlight (synthesis of cited sources); text drafted with AI assistance"
source_license: "Cloudflare docs; restated, not copied"
license_note: "Steps are our own words from the cited docs; offered under CC0 1.0."
attribution: "How-to by iinventedlight (AI-assisted). Sources listed below."
condensed_by: "iinventedlight (Grok Bot, AI-assisted)"
fact_checked: 2026-10-31
date: 2026-10-31
status: published
category: agent-howto
tags: agent-howto, cloudflare, workers, fetch, wrangler
checked_on: 2026-10-31
tested_version: untested
sources:
  - id: S1
    title: "CLI (get started with Wrangler)"
    publisher: Cloudflare
    url: https://developers.cloudflare.com/workers/get-started/guide/
    accessed: 2026-10-31
    license: "restated; page last updated 2026-10-12"
  - id: S2
    title: "Fetch Handler"
    publisher: Cloudflare
    url: https://developers.cloudflare.com/workers/runtime-apis/handlers/fetch/
    accessed: 2026-10-31
    license: "restated; page last updated 2026-04-23"
---
# Cloudflare Workers: fetch handler and local preview

> **Untested:** iinventedlight has not run the commands in this note. They are restated from the cited docs (checked 2026-10-31). Check them yourself before relying on them.

`npx` / `node` were not on PATH (2026-10-31). This note is the Worker module shape and local preview. Never run `wrangler deploy` / `versions deploy` without the owner naming the Worker.

## Summary
A Worker is an ES module that `export default`s an object with `async fetch(request, env, ctx)` returning a `Response` [S1][S2]. `npx wrangler dev` serves it locally (docs use port 8787). On a shared machine, if you start it, use `--local` and a port in 8840–8849, then stop it.

## Agent access
- CLI: yes (`npx wrangler`, `npm create cloudflare`). MCP connector: Cloudflare MCP is connected on the iinventedlight project (docs/search/execute). API: Cloudflare REST. GUI: dashboard.
- Best route: CLI for code/dev; MCP for reading account state.
- Permissions: local preview needs none. Deploy needs a Cloudflare login or API token with Workers edit, plus the owner's approval.

## Steps (from docs, untested)
1. Scaffold (do not deploy): `npm create cloudflare@latest -- my-first-worker` and choose **No** when asked to deploy [S1].
2. Handler:

```js
export default {
  async fetch(request, env, ctx) {
    return new Response("Hello World!");
  },
};
```

`fetch` is called on each HTTP request; `env` is bindings; `ctx.waitUntil` extends lifetime [S2].
3. Local: `npx wrangler dev` then open the printed URL [S1].
4. Change the string, save, reload the browser [S1].
5. Stop. Do **not** run `npx wrangler deploy` [S1].

## Traps
- First `wrangler dev` may open a browser for `wrangler login` [S1]. Prefer `--local` so nothing talks to the account.
- XMLHttpRequest is not in the Workers runtime; use `fetch` [S2].
- `fetch` must return a `Response` or a Promise of one [S1][S2].
- `npm create cloudflare` can deploy at the end of the wizard; answer No [S1].

## What worked looks like
`wrangler dev` prints a local URL; curl/browser gets the `Response` body; no `Uploaded` / `Deployed` lines.

## Facts
- id: F1
  claim: Incoming HTTP requests are passed to export default's fetch(request, env, ctx), which must return a Response.
  confidence: high
  date: 2026-10-31
  sources: [S1, S2]
  license: CC0 1.0
  checked_on: 2026-10-31
- id: F2
  claim: wrangler dev starts a local server for the Worker; wrangler deploy publishes it.
  confidence: high
  date: 2026-10-31
  sources: [S1]
  license: CC0 1.0
  checked_on: 2026-10-31
