Skip to content
GitHubXDiscordRSS

Local Development

Alchemy’s development mode provides a local development experience for Cloudflare Workers, featuring hot reloading, local resource emulation, and seamless integration with remote Cloudflare services.

To run Alchemy in development mode, use the alchemy dev command to:

  • Emulate Cloudflare Workers and associated resources locally
  • Watch for and auto-apply changes to your infrastructure
  • Hot reload Workers when you make changes to your runtime code
Terminal window
bun alchemy dev

You can also specify additional options:

Terminal window
# run dev mode with default settings
bun alchemy dev
# specify a stage
bun alchemy dev --stage dev
# use a custom script
bun alchemy dev ./my-infra.ts
# use an environment file
bun alchemy dev --env-file .env.dev

In development mode, the Cloudflare Worker resource runs in Miniflare, a local environment that emulates the Cloudflare Workers runtime. By default, Workers run on the first available port beginning at 1337:

const worker = await Worker("my-worker", {
entrypoint: "worker.ts",
});
console.log(worker.url); // http://localhost:1337

You can also set a custom port for the Worker:

const worker = await Worker("my-worker", {
entrypoint: "worker.ts",
dev: {
port: 3000,
},
});
console.log(worker.url); // http://localhost:3000

Most Cloudflare bindings are automatically emulated in development mode, such as D1Database, KVNamespace, and R2Bucket:

const d1 = await D1Database("my-d1");
const kv = await KVNamespace("my-kv");
const r2 = await R2Bucket("my-r2");
const queue = await Queue("my-queue");
const worker = await Worker("my-worker", {
entrypoint: "worker.ts",
bindings: {
D1: d1,
KV: kv,
R2: r2,
QUEUE: queue,
},
});

Secrets and plain-text bindings are also supported with no additional configuration:

const worker = await Worker("my-worker", {
entrypoint: "worker.ts",
bindings: {
PLAIN_TEXT: "Hello, world!",
API_KEY: alchemy.secret("pk_dev_1234567890"),
},
});

By default, development mode emulates supported resources locally. To use the real resource from Cloudflare, set the dev.remote option:

const kv = await KVNamespace("my-kv", {
dev: {
remote: true,
},
});
const worker = await Worker("my-worker", {
entrypoint: "worker.ts",
bindings: {
KV: kv,
},
});

Alchemy integrates with popular web frameworks, so you can use them with Alchemy’s development mode and access local resources. Typically, you’ll need to update your framework’s configuration with the relevant Alchemy adapter or plugin. For example:

First, use the Astro resource in your alchemy.run.ts script:

alchemy.run.ts
import { Astro } from "alchemy/cloudflare";
const astro = await Astro("my-astro-app");

Then, update your astro.config.mjs file:

astro.config.mjs
import alchemy from "alchemy/cloudflare/astro";
export default defineConfig({
integrations: [alchemy()],
});