Your Worker exists, but you haven't seen it run. In this lesson you'll run it on your laptop, teach it two answers, and write tests that prove both. The tests run inside the same runtime Cloudflare uses, so what passes here behaves the same once it's live.
Verified node 24.22.2wrangler 4.157.0vitest 5.0.5typescript 5.9.3
Start from a-02 on GitHub. Starting here, or behind? Get the code at that tag:
git clone https://github.com/ryanyogan/klippy cd klippy git checkout a-02
1. Run it
From klippy/, start the local server:
pnpm devThat runs wrangler dev in apps/agent (the root script from the last lesson). It prints Ready on http://localhost:8787. Open that address in your browser and you'll see "Hello World!". Leave this terminal running and open a second one for the commands below.
wrangler dev runs workerd, the open-source Workers runtime, on your machine. Save a change to your code and it reloads by itself.
If port 8787 is taken, run pnpm dev --port 8801 instead and use that port below. Our recordings use 8801.
2. A route and a 404
Right now every address answers "Hello World!". Klippy should answer at its home page, /, and say "Not found" for anything else. Replace apps/agent/src/index.ts with:
new URL(request.url)splits the address into parts, so you can read itspathname:/for the home page,/nopeforhttp://localhost:8787/nope.A
Responseis a body plus a status. Leave the status out and it's200 OK.404tells the caller, and any program reading the answer, that nothing lives there.We dropped the
envandctxarguments c3 had. This code doesn't use them yet.envcomes back in the next lesson.
Ask it with curl, a command that sends a request and prints the answer. -i shows the status line and headers too:
The first terminal logs each request, like GET / 200 OK (20ms). If curl says "connection refused", the dev server isn't running, or it's on another port.
3. Types for what your Worker can reach
Your Worker will soon reach Cloudflare services: an AI model, a database. Each one arrives on env, and wrangler types reads wrangler.jsonc and writes their types into worker-configuration.d.ts. Run it now so you know the command:
pnpm --filter agent run cf-typegenEnv is empty: nothing is connected yet. You'll run this again each time you add something to wrangler.jsonc.
4. Two tests
A test is code that runs your code and checks the answer. Replace apps/agent/test/index.spec.ts with:
SELFis your Worker, running inside workerd for the test.SELF.fetchsends it a request, as curl did. The host,example.com, doesn't matter: the request never leaves your machine.expect(...).toBe(...)fails the test if the two don't match.Each
itis one test with a sentence that says what should be true.
5. A typecheck, then run everything
TypeScript only checks your types when you ask it to. Add a typecheck script to apps/agent/package.json. It checks the Worker, then the tests, which have their own tsconfig.json:
And one line to the root package.json, so pnpm typecheck checks every app:
Now run both from klippy/:
pnpm typecheck pnpm test
pnpm typecheck prints nothing when all is well; an error names the file and line. If a test fails, vitest shows what it expected and what it got: a typo in "Hi, I am Klippy." is the usual one.
Save your work with git add -A and git commit -m "Hello, Worker".
Stuck? Compare with tag a-03 (changes from a-02).