The tightest feedback loop from edit to production
Cloud programs composed from Layers: type-checked, emulated locally, tested live, and deployed per pull request.
Every step is optimized
Iterate on your machine and then let CI deploy a preview, test it, and ship it on merge. The type checker answers in milliseconds, emulated tests in seconds, and the real cloud in about 20 seconds.
See the example app and benchmark on GitHub
Your machine · edit
Infrastructure is part of your application
Other IaC tools split an app into two programs, but every feature you build crosses that line. In Alchemy, a Layer owns its infrastructure and service implementation so that features can be decomposed.
- InfrastructurePhotos bucket
- Configuration & policiesread/write binding
- APIs & business logicupload()
- Frontendupload button
export class Photos extends Context.Service<Photos, { upload(name: string, body: string): Effect.Effect<void>; }>()("Photos") {} export const PhotosR2 = Layer.effect( Photos, Effect.gen(function* () { // resource const bucket = yield* Cloudflare.R2.Bucket("Photos"); // binding: read/write access for this Worker only const photos = yield* Cloudflare.R2.ReadWriteBucket(bucket); // API return { upload: (name, body) => photos.put(name, body), }; }), );
Your machine · type-check
Type checking proves your infra is correct
Each Layer declares what it needs in its type: the resources it creates, the access it grants, and the services it calls. Leave one out and the program doesn't compile, so a broken stack fails in your editor in milliseconds, before anything deploys.
Your machine · test, emulated
Get fast feedback with local emulation
alchemy dev runs Workers, Durable Objects, queues and buckets on emulated services on your machine, and the frontend reloads as you type. Set dev: true in a test and the same suite runs against those services in seconds, with nothing deployed.
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 }; }), );
Your machine · test, live
Test a live deployment when ready to PR
Once it works locally, run the same test without LOCAL=1. It deploys the app to a stage of its own, runs against real Workers, buckets and permissions, and destroys the stage afterwards, in about 20 seconds.
const { test, beforeAll, afterAll, deploy, destroy } = Test.make({ providers: Cloudflare.providers(), dev: !!process.env.LOCAL, // emulated, or the real cloud }); const stack = beforeAll(deploy(Stack)); // its own stage afterAll(destroy(Stack)); 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!"); }));
CI/CD · preview per PR
Deploy a preview stage in CI before merging
CI deploys each pull request to its own stage, runs the same tests, and comments a link to try it. The comment is a resource in the same program, so it is updated on every push and deleted with the preview. Merging deploys to production.
const api = yield* Api;const pr = yield* Config.option(Config.Int("PULL_REQUEST"));const sha = yield* Config.String("GITHUB_SHA"); if (Option.isSome(pr)) { yield* GitHub.Comment("Preview", { owner: "acme", repository: "my-app", issueNumber: pr.value, body: Output.interpolate`Preview: ${api.url} (${sha})`, allowDelete: true, });}
Production · monitoring
Disciplined monitoring on Day 1
Provide one Layer and every request is traced and logged with OpenTelemetry from the first deploy. Its datasets, dashboards and alert monitors are resources in the same program, so monitoring ships with the app. Swap the Layer to send telemetry to a different platform.
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