Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Sets up Alchemy (alchemy-run/alchemy, Infrastructure-as-TypeScript) in any codebase — new project scaffold OR add to existing app. Wires Cloudflare/AWS providers, state backend, secrets, and binding types end-to-end with strict secret hygiene. USE THIS SKILL whenever the user mentions "alchemy", "alchemy.run", "Infrastructure as TypeScript", or asks to deploy a Worker/Lambda/D1/R2/KV/Queue/DO via TS, add a state backend, configure ALCHEMY_PASSWORD, generate alchemy.run.ts, replace SST/Pulumi/CDK
.claude/skills/aashirjaved-alchemy-infra/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 40% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 55% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 119% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 75% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 42% | 0% |
You are configuring Alchemy — an ESM-only, TypeScript-native IaC library where resources are async functions you await. State lives in JSON files (default), Cloudflare DO, S3, or SQLite. Secrets are encrypted with ALCHEMY_PASSWORD.
This skill is interactive. Do not guess the user's situation. Run the Intake below first, then branch.
Ask the user these questions in a single batched prompt (use the AskUserQuestion tool if available; otherwise plain text with numbered options). Do not skip — the answers change every subsequent decision.
alchemy login), CF API token in env, AWS profile, or "I'll do it later".$USER), per-branch PR previews (pr-<n>), explicit prod/staging/dev.Follow up only if answers are contradictory or block progress. Don't over-interrogate.
Before touching anything, run:
bashls package.json tsconfig.json alchemy.run.ts wrangler.toml wrangler.jsonc sst.config.ts pulumi.yaml cdk.json 2>/dev/null
If alchemy.run.ts already exists, read it first and treat the task as a modification, not a fresh install. If wrangler.toml/sst.config.ts/pulumi.yaml exist, the user is migrating — confirm before deleting any of those.
Based on intake answer for runtime + start point:
New project from template (preferred when starting fresh):
bashbunx alchemy create <name> --template=<typescript|vite|nextjs|sveltekit|nuxt|astro|tanstack-start|react-router|redwood|bun-spa>
Add to existing project:
bash# pick the package manager that matches the repo bun add alchemy # or: pnpm add / npm install / yarn add bunx alchemy init # optional: --framework <name> --yes
Verify install:
bashnode -e "console.log(require('alchemy/package.json').version)"
Alchemy is ESM-only. If the repo is CommonJS, set "type": "module" or move IaC code to .mts / .ts files compiled with ESM target.
alchemy.run.tsAlways place at repo root. Skeleton (cloud-agnostic core, add provider blocks per intake):
tsimport alchemy from "alchemy"; // import per cloud — examples: // import { Worker, KVNamespace, R2Bucket, D1Database } from "alchemy/cloudflare"; // import { Function, Table, Bucket } from "alchemy/aws"; const app = await alchemy("APP_NAME_HERE", { phase: process.argv.includes("--destroy") ? "destroy" : "up", // stage: process.env.STAGE, // uncomment if multi-stage // password: process.env.ALCHEMY_PASSWORD, // already default, set for clarity }); // === resources go here === // export const worker = await Worker("api", { entrypoint: "./src/worker.ts" }); await app.finalize();
Required rules:
async function, not arrow, for any custom Resource.await app.finalize() must be the last statement in the up path. Without it, orphans are not GC'd.alchemy.secret(process.env.X). Never inline a literal token.See references/cloudflare.md and references/aws.md for full resource shapes.
Follow references/security.md in full. Quick checklist:
scripts/gen_password.sh (32+ bytes, base64). Write to .env. Never commit.openssl rand -base64 32..gitignore — must contain: .env .env.* !.env.example .alchemy/ node_modules/ .wrangler/ Run scripts/gitignore_check.sh to verify.
.env.example — list every variable name with empty value. Commit this file; never commit .env.alchemy.run.ts literally. Always pull from process.env and wrap with alchemy.secret().git status shows .env, .alchemy/, or any file with *.pem, *.key, credentials.json. Surface and stop.Default filesystem is fine for solo dev. For team/CI use Cloudflare or S3.
ts// Cloudflare DO-backed (recommended for shared state) import { CloudflareStateStore } from "alchemy/state"; const app = await alchemy("my-app", { stateStore: (scope) => new CloudflareStateStore(scope, { stateToken: alchemy.secret(process.env.ALCHEMY_STATE_TOKEN), }), }); // S3 import { S3StateStore } from "alchemy/aws"; new S3StateStore(scope, { bucketName: "my-app-alchemy-state", region: "us-east-1" }); // SQLite local import { SQLiteStateStore } from "alchemy/state"; new SQLiteStateStore(scope, { filename: ".alchemy/state.sqlite" });
If the user picks CloudflareStateStore, the alchemy-state-service Worker auto-deploys on first run.
Branch on intake:
bun alchemy configure && bun alchemy login. Tokens land in ~/.alchemy/credentials/<profile>/cloudflare.json. Tell user to keep that dir private.CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID to .env. Mint a token with minimal scopes (Workers Scripts:Edit, KV/R2/D1/Queue:Edit as needed, Account:Read). Show the scoped permissions list, don't reuse Global API Key unless they insist.AWS_PROFILE / AWS_ACCESS_KEY_ID / SSO. Never write long-lived AWS keys into the repo.See references/frameworks.md. One block per framework. Key invariants:
alchemy() plugin from alchemy/cloudflare/vite to vite.config.ts.@opennextjs/cloudflare, add open-next.config.ts, use Nextjs(...) resource.svelte.config.js adapter alchemy/cloudflare/sveltekit.astro.config.mjs adapter alchemy/cloudflare/astro with output: "server".Add these (preserve existing scripts):
json{ "scripts": { "deploy": "alchemy deploy", "destroy": "alchemy destroy", "dev": "alchemy dev", "run": "alchemy run" } }
If dev/deploy are already taken, prefix with alchemy: instead of overwriting.
bun tsc --noEmit (or tsc --noEmit) — must pass.bun alchemy run --stage local — should print outputs without mutating cloud.bun alchemy dev — Miniflare boots, hot reload works.bun alchemy deploy --stage <name>.If type-check fails on missing binding types, add to types/env.d.ts:
tsimport type { worker } from "../alchemy.run.ts"; declare module "cloudflare:workers" { namespace Cloudflare { export interface Env extends typeof worker.Env {} } }
See references/cicd.md for the canonical GitHub Actions setup with per-PR stages, secret injection, and a destroy job on PR close. Always include the safety check refusing to destroy prod.
await app.finalize() → orphans accumulate.phase: "destroy" halts the script — code after await alchemy(...) never runs.url: true Worker preview URLs are incompatible with Durable Objects in prod — use routes/domains.ALCHEMY_PASSWORD after secrets are stored corrupts decryption. Rotation procedure is not officially documented; treat the password as permanent..alchemy/ works only for single-developer projects. For teams, switch state backend before the first deploy.async function, not arrow.For custom Resource authoring, see references/custom-resources.md. For troubleshooting failed deploys, see references/troubleshooting.md.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | 14,012 | 5,439 | -61% | 1 | 1 | 0% | 3,339 | 3,592 | +8% | 0 | 0 | — |
case-02 | fail→fail | 11,864 | 5,859 | -51% | 1 | 1 | 0% | 2,423 | 3,923 | +62% | 0 | 0 | — |
case-03 | fail→fail | 14,929 | 5,455 | -63% | 1 | 1 | 0% | 3,170 | 3,760 | +19% | 0 | 0 | — |
case-04 | pass→fail | 4,374 | 7,217 | +65% | 1 | 1 | 0% | 1,027 | 4,015 | +291% | 0 | 0 | — |
case-05 | pass→pass | 5,053 | 6,778 | +34% | 1 | 1 | 0% | 1,106 | 4,045 | +266% | 0 | 0 | — |
case-06 | pass→fail | 6,131 | 7,576 | +24% | 1 | 1 | 0% | 1,424 | 4,249 | +198% | 0 | 0 | — |
case-07 | pass→pass | 12,224 | 3,362 | -72% | 1 | 1 | 0% | 2,009 | 3,289 | +64% | 0 | 0 | — |
case-08 | fail→pass | 13,672 | 4,524 | -67% | 1 | 1 | 0% | 2,440 | 3,419 | +40% | 0 | 0 | — |
case-09 | fail→pass | 12,852 | 4,828 | -62% | 1 | 1 | 0% | 2,256 | 3,492 | +55% | 0 | 0 | — |
case-14 | fail→pass | 9,704 | 7,030 | -28% | 1 | 1 | 0% | 1,818 | 3,981 | +119% | 0 | 0 | — |
case-10 | fail→pass | 11,659 | 6,920 | -41% | 1 | 1 | 0% | 2,198 | 3,841 | +75% | 0 | 0 | — |
case-11 | pass→pass | 9,731 | 4,906 | -50% | 1 | 1 | 0% | 1,698 | 3,601 | +112% | 0 | 0 | — |
case-12 | fail→pass | 12,810 | 5,788 | -55% | 1 | 1 | 0% | 2,595 | 3,685 | +42% | 0 | 0 | — |
case-13 | fail→pass | 8,018 | 4,517 | -44% | 1 | 1 | 0% | 1,724 | 3,488 | +102% | 0 | 0 | — |
case-15 | fail→pass | 8,910 | 7,712 | -13% | 1 | 1 | 0% | 1,706 | 4,034 | +136% | 0 | 0 | — |
case-16 | fail→pass | 9,754 | 7,988 | -18% | 1 | 1 | 0% | 1,970 | 4,188 | +113% | 0 | 0 | — |
case-17 | fail→pass | 8,909 | 2,613 | -71% | 1 | 1 | 0% | 1,869 | 3,049 | +63% | 0 | 0 | — |
case-18 | fail→pass | 7,085 | 2,846 | -60% | 1 | 1 | 0% | 1,456 | 3,177 | +118% | 0 | 0 | — |
case-19 | pass→pass | 10,165 | 2,995 | -71% | 1 | 1 | 0% | 2,223 | 3,197 | +44% | 0 | 0 | — |
case-20 | pass→pass | 8,785 | 6,589 | -25% | 1 | 1 | 0% | 1,608 | 3,712 | +131% | 0 | 0 | — |
case-21 | pass→pass | 9,155 | 5,777 | -37% | 1 | 1 | 0% | 1,613 | 3,668 | +127% | 0 | 0 | — |
case-22 | fail→pass | 9,150 | 6,891 | -25% | 1 | 1 | 0% | 1,783 | 3,712 | +108% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +41 percentage points is the difference between those two pass rates over the 22 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.