Part 4: Local Dev
In Part 3 you wrote integration tests against
your deployed stack. But deploying to Cloudflare on every code change
is slow. In this part you’ll use alchemy dev to run everything
locally with hot reloading.
Start dev mode
Section titled “Start dev mode”alchemy devThat’s it. Alchemy deploys your stack to the cloud and proxies requests to Workers running locally in workerd. It watches for file changes and hot reloads your Worker automatically.
Your Worker is available at http://localhost:1337 by default:
curl http://localhost:1337/hello.txtHow it works
Section titled “How it works”alchemy dev does three things:
- Deploys to the cloud — resources like R2 Buckets are created on Cloudflare, while Workers run locally in workerd
- Watches for changes — when you edit
src/worker.tsor any file it imports, the Worker is rebuilt and reloaded instantly - Preserves local state — data in your local R2 Bucket persists across restarts
The same alchemy.run.ts is used for both dev and deploy — no
separate dev config needed.
Custom port
Section titled “Custom port”Set a custom port for your Worker:
export default Cloudflare.Worker( "Worker", { main: import.meta.path, dev: { port: 3000, }, }, // ...);Run tests in dev mode
Section titled “Run tests in dev mode”You don’t need to run alchemy dev in a separate terminal to test
against locally-emulated resources. The test harness has its own
dev flag that flips every Worker over to workerd inside the test
process — same wiring as alchemy dev, no extra terminal.
const { test, beforeAll, afterAll, deploy, destroy } = Test.make({ providers: Cloudflare.providers(), state: Cloudflare.state(), dev: true,});beforeAll(deploy(Stack)) now boots the Workers locally; HTTP
assertions hit http://localhost:1337 and roundtrip into your code
with full stack traces.
Toggle dev mode from CI
Section titled “Toggle dev mode from CI”Hardcoding dev: true would force CI runs to local emulation too.
Read it from the environment instead so the same test file runs
against real cloud resources in CI and locally-emulated ones on your
laptop.
const { test, beforeAll, afterAll, deploy, destroy } = Test.make({ providers: Cloudflare.providers(), state: Cloudflare.state(), dev: true,});Drop the explicit flag and the harness falls back to the
ALCHEMY_DEV env var — set ALCHEMY_DEV=1 in your shell to flip
to local mode, leave it unset in CI.
ALCHEMY_DEV=1 bun test test/integ.test.tsYou now have:
- Local development with
alchemy dev - Hot reloading on file changes
- Local emulation of Cloudflare resources
In Part 5, you’ll set up GitHub Actions for automated deployments and PR preview environments.