Reach for the better primitives
Snap together cloud resources and let Alchemy do the wiring so you can focus on your product.
The full picture
Alchemy can deploy, test, and destroy your app. That's everything you need to have a full CI experience with branch previews and live test on real infratructure. Oh and the graphic below is how long it actually takes; Alchemy does all of that in ~25 seconds.
See the example app and benchmark on GitHub
Run your entire stack locally
As apps grow you have more and more services; each backend service needs to be started in a local emulator or proxy a live service, each client needs its own dev server, and you have to set up HMR. alchemy dev manages all of that for you, 1 command, no extra configuration, and all your services just start.
import Api from "./src/api.ts"; export default Alchemy.Stack( "my-app", { providers: Cloudflare.providers() }, Effect.gen(function* () { // backend: a Cloudflare Worker, run locally in workerd const api = yield* Api; // frontend: a Vite app that calls it const web = yield* Cloudflare.Website.Vite("Web", { env: { VITE_API_URL: api.url }, }); return { web: web.url, api: api.url }; }), );
Run tests against real infrastructre
alchemy test deploys a temporary stack, runs your tests against it, then tears it down. This way tests hit a real environment instead of mocks or local emulation, and agent loops stay accurate. In CI, tests can inherit the preview deployment stack so deploy doesn't run twice.
// each suite deploys its own isolated stack const stack = beforeAll(deploy(Stack)); // real R2, real DynamoDB afterAll(destroy(Stack)); // torn down at the end test("PUT + GET round-trips through R2", Effect.gen(function* () { const { url } = yield* stack; const res = yield* HttpClient.get(`${url}/object/hello.txt`); expect(yield* res.text).toBe("hi!"); }));
Dry run before you deploy
plan does a dry-run and show what will change.deploy updates your infrastructure to match the desired state. destroy tears it all down (with safe guards to prevent accidental data deletion). Simple enough for agents, easy enough you'll choose to use it too
export const Photos = Cloudflare.R2.Bucket("Photos"); export const Sessions = Cloudflare.KV.Namespace("Sessions"); const Bindings = Layer.mergeAll( Cloudflare.R2.ReadWriteBucketBinding, Cloudflare.KV.ReadWriteNamespaceBinding, ); export default Cloudflare.Worker( "Api", { main: import.meta.url }, Effect.gen(function* () { const photos = yield* Cloudflare.R2.ReadWriteBucket(Photos); const kv = yield* Cloudflare.KV.ReadWriteNamespace(Sessions); return { fetch: Effect.gen(function* () { const { objects } = yield* photos.list(); const user = yield* kv.get("user"); return yield* HttpServerResponse.json({ user, objects }); }), }; }).pipe(Effect.provide(Bindings)), );
Wired for observability
Alchemy has logs, spans, and metrics set up by default. The exporter is an Effect Layer so changing providers is a 1 line swap, whether its Axiom, Datadog, or any other OTLP endpoint.
Dashboards and alarms are resources themselve so you can define them right next to the resources they are responsible for.
const requestsTotal = Metric.counter("requests_total"); // any OTLP endpoint: Axiom, Datadog, Honeycomb, a collector… const Otel = Alchemy.Telemetry.layerOtlp({ url: "https://otlp.example.com", }); export default Cloudflare.Worker( "Api", { main: import.meta.url }, Effect.gen(function* () { yield* Effect.logInfo("request received"); yield* Metric.increment(requestsTotal); return { fetch: handler }; }).pipe(Effect.provide(Otel)), );
export const Dashboard = AWS.CloudWatch.Dashboard("ApiHealth", { widgets: [ Widget.line({ title: "p99 latency", metric: api.metrics.p99 }), Widget.line({ title: "requests/s", metric: api.metrics.rps }), Widget.number({ title: "5xx", metric: api.metrics.errorRate }), ], }); export const P99Alarm = AWS.CloudWatch.Alarm("p99Latency", { metric: api.metrics.p99, threshold: 500, alarmActions: [pagerDuty, slackWebhook], });
Loved by the people shipping with it
What builders say after putting Alchemy in front of their agents, their Cloudflare apps, and their production infrastructure.
Rhys@RhysSullivanAlchemy enables me to be more ambitious in shipping large projects to multiple targets. It gives my agents the capability to debug issues against real deployments of my systems, enabling the best feedback loop I've ever had resulting in several large perf wins.
Maximilian@maxedappsCloudflare + Alchemy + Effect is such a winning stack with AI agents, it's not even real. … And all the infra lives in code - which is how it should be with AI agents.
Superlinear@superlinear_fmWe use @alchemy_run bc it's truly declarative, written in TypeScript with Effect, and gives agents a clean, code-native way to understand and modify infrastructure.
carlo@seitandelivery… I just read the v2 docs and I never thought iac could be this good 😍 seriously, this is a game changer for me. Thank you all for the hard work 🫶 alchemy will be my new obsession this year haha
Andrew Jefferson@EastlondonDevAlchemy is next gen infrastructure as code & it's helping us make the most of Cloudflare's global scale
Dill@dillionv… rn use some janky pulumi / terraform deploy process and would rather just migrate it all to effect + alchemy
Alessandro@alessandroc00c… i am loving alchemy and im spinning up s***t like crazy
Alireza Najafi@alire8zaAlchemy made working with Cloudflare joyful
Michael Arnaldi@MichaelArnaldiThanks to Alchemy the CF primitives finally shine in DX, I couldn't get over the DX issues before, now it's amazing
Dillon Mulroy@dillon_mulroyalchemy is so good for IAC, esp. cloudflare IAC
Nick Blow@NickBlowThe fact it's truly “just typescript” and not the abomination of codegen … Allows it to be far more easily extended than other iac platforms.
arth@arthtychoosing alchemy as a core foundation on @op0ai is probably a top 3 decision long-term. so far, the dx and velocity has gone thru the roof.
artem@flowisgreatusing alchemy for conare.ai and it's awesome - thanks for the hard work! having all of the backend directly as code is a game changer for AI
Nipsuli@NipsuliAlchemy is freaking amazing! I've run with cloudflare workers for few years now in different projects and alchemy made the experience so freaking much better.
Michael Arnaldi@MichaelArnaldiEffect + Alchemy + DOs (and cf primitives) is an insanely powerful combo
joel@joelhooksnobody talking about the effect+alchemy+cloudflare combo to literally build f'n anything
Maxwell Brown@maxwellbrownAlchemy is literally the only reason I gave Cloudflare's dev platform a shot. The fact that I can just write Effect code to describe / deploy my infra and then use those same resources in my program is unparalleled DX IMO.
skuse@skuse_Man I've been here 2 days and this is such an underrated project, having my whole stack defined as code even things like stripe is a complete game changer. Define the code, dump the necessary outputs into my servers env, just works. Testing / isolating environments has become trivial whereas before I'd have to click around dashboards.
david@davidlbowman… what i love about alchemy-effect, is i already write 100% effect code, but quite a few of my clients are smaller, and only need a static site, some webhook handlers, maybe a workflow, and it's nice to be able to quickly create those layers. … so far, it's been great.
Harry Solovay@harrysolovayIt just hit me: @alchemy_run is going to Effect-pill literally everyone who wants to ditch Wrangler. ... that's pretty magical.
dan myles@danmyles_IaC is a no brainer for anything bigger than a vibecoded saas just too much custom tooling required for dev stages etc on TF/pulumi why i love alchemy!
Michael Arnaldi@MichaelArnaldiv4 + alchemy solved most of the issues, we are now focusing on higher level design of things like Cluster on CF
Ray@xesrevinuAlchemy architecture is really amazing. It's really amazing work. I feel that you have made such an excellent project.
Get started.
- Install
pnpm add alchemy@latest effect - Paste this into your coding agent
Help me build an Alchemy app on Cloudflare. Start by reading https://alchemy.run/getting-started and follow it exactly: scaffold a fresh project, install the dependencies, create the `alchemy.run.ts` Stack with a single Cloudflare R2 Bucket (no Worker yet), and run `alchemy deploy` so I sign in to Cloudflare and provision the Bucket. Confirm the Bucket is live before moving on. Then STOP and ASK ME what I want to build. From there, consult only the docs you need for what I asked for — don't march me through every tutorial. A Worker only gets added later if what I want to build needs one (the tutorial covers that in part-2). Tutorial — foundations, work through whichever parts I haven't touched: https://alchemy.run/cloudflare/tutorial/part-1 First Stack (state store + first resource) https://alchemy.run/cloudflare/tutorial/part-2 Add a Worker https://alchemy.run/cloudflare/tutorial/part-3 Testing https://alchemy.run/cloudflare/tutorial/part-4 Local Dev (`alchemy dev`) https://alchemy.run/cloudflare/tutorial/part-5 CI/CD (per-PR previews from GitHub Actions) For everything else (Cloudflare deep-dives, guides, concepts), fetch https://alchemy.run/llms.txt — it's the index of the guide and concept docs. Use it to look up the specific page you need instead of guessing URLs. The per-resource API reference is indexed separately in https://alchemy.run/llms-full.txt — it's large, so only fetch it when you need a specific resource's reference page. Important: - Confirm with me before each deploy. Don't batch. - Do NOT instruct me to export CLOUDFLARE_ACCOUNT_ID or CLOUDFLARE_API_TOKEN. Alchemy stores credentials in profiles — `alchemy profile edit` (or the first `alchemy deploy`) prompts interactively for OAuth or an API token and saves it to ~/.alchemy/profiles.json. - Use pnpm: `pnpm add` to install packages and `pnpm alchemy deploy` to deploy. - If I'm migrating from Alchemy v1 (async/await), find the v1 migration guide via llms.txt and read it first. - Ship
pnpm alchemy deploy