Skip to content

Local development

alchemy dev runs your stack on your machine. Your compute runs locally (Workers in workerd, Lambda and ECS in Docker containers), the services around it are emulated, and code changes hot reload in milliseconds. Alchemy.remote() runs any resource against the real cloud when you need it.

This page covers the concepts shared by every cloud. For what each cloud emulates and how, see the dedicated guides:

  • Cloudflare local development — Workers in workerd; simulators for KV, R2, D1, Queues, Hyperdrive, Workflows, Containers, and the Worker binding surface (browser rendering, images, email, cron, Stream, …).
  • AWS local development — Lambda and ECS in Docker containers with close to 40 emulated services (S3, DynamoDB, SQS, SNS, EventBridge, API Gateway, …), no AWS account required.
Terminal window
alchemy dev
 Bucket (Cloudflare.R2.Bucket) created (local)
 DB (Cloudflare.D1.Database) created (local)
 Worker (Cloudflare.Worker) created (local → workerd)
  • http://localhost:1337

Watching for changes ...

Three things happen:

  1. Emulatable services run locally — resources whose provider ships a local implementation are created as local simulators with dev:-prefixed ids. No cloud calls.
  2. Your code runs locally — Workers execute in workerd, Lambda functions and ECS tasks in Docker containers, websites on their framework’s own dev server — with bindings wired to the local simulators.
  3. File changes hot reload — edit your code and the running compute swaps in the new code without a redeploy.

Resources whose provider has no local implementation deploy to the real cloud, into your personal stage (dev_$USER by default), so your loop never collides with teammates or prod. A stack that mixes emulated and live-only resources just works.

Watching for changes ...

 src/worker.ts changed
  • Rebuilding worker ...
 Worker reloaded in 42ms

 src/api.ts changed
  • Rebuilding worker ...
 Worker reloaded in 38ms
  • Code changes take effect in milliseconds, not minutes
  • Resources stay running across reloads — only your application code is rebuilt

Arbitrary dev processes — Vite, Next, anything with a dev server — join the loop via Command.Dev: started by alchemy dev, restarted when its inputs change, and a no-op on deploy.

In dev, emulatable resources are simulators. A local resource’s id is dev:-prefixed, which doubles as proof that no cloud call ran.

The local simulators reach beyond your compute’s bindings. Node-side capability clients follow the same rule: a seed script in an Action that writes to a dev: KV Namespace or S3 bucket lands in the same local simulator your Worker or Lambda reads.

Every other resource runs live in dev automatically, and Alchemy.remote() (below) runs an emulatable resource against the real cloud when local fidelity isn’t enough.

Because your code runs locally, you can attach a debugger:

  • Set breakpoints in your IDE
  • Inspect variables and call stacks
  • Profile performance

Alchemy.remote() opts a resource out of local emulation — “run this live even in dev”:

import * as Alchemy from "alchemy";
const worker = yield* Worker("Api", { ... }).pipe(Alchemy.remote());

During alchemy deploy the pin is a no-op — everything is live anyway. If a remote resource needs credentials you don’t have, alchemy dev tells you before touching anything.

yield* Effect.gen(function* () {
const api = yield* Worker("Api", { ... });
const site = yield* Worker("Site", { ... });
}).pipe(Alchemy.remote());

The policy is ambient and captured at registration (like adopt()), so everything inside the scope runs live. Resources with no local emulation already run live in dev — remote() on them is a no-op.

Local and live compose into hybrid topologies — a local Worker producing into a live queue whose local consumer drains it, or a local Lambda reading a live Secrets Manager secret. See the per-cloud guides for examples.

When a resource moves between local and live — you deploy after a dev session, or add/remove remote() — it’s planned as a replacement: the new instance is created live, and the local one (the workerd instance, the Docker container, the dev process) is torn down. Dev state never silently becomes cloud state.

alchemy dev alchemy deploy
Emulatable services Local simulators (remote() for live) Deployed to cloud
Everything else Deployed to cloud (personal stage) Deployed to cloud
Application code Runs locally (workerd, Docker) Deployed to cloud
File watching Hot reload on change Manual redeploy
Debugging Attach local debugger Tail logs
Speed Milliseconds Seconds to minutes

To automate the deploy side, see the CI guide.

  • Cloudflare local development — what runs in workerd and which bindings are simulated.
  • AWS local development — the emulated AWS surface, Lambda/ECS containers, and zero-credential dev.
  • CI — deploy the same stack from GitHub Actions with PR previews.
  • Stages — how dev_$USER, pr-42, and prod stay isolated.
  • Dev servers — run any framework dev server as a Command.Dev resource in the dev loop.
  • Local Providers — build the local implementation of a resource.