├── .gitmodules ├── CLAUDE.md ├── .eslintignore ├── examples ├── docker │ ├── .gitignore │ ├── .env │ ├── tsconfig.json │ └── package.json ├── cloudflare-astro │ ├── .gitignore │ ├── astro.config.mjs │ ├── src │ │ ├── env.d.ts │ │ └── pages │ │ │ └── api │ │ │ └── hello.ts │ ├── tsconfig.json │ └── alchemy.run.ts ├── planetscale-drizzle │ ├── .gitignore │ ├── database │ │ ├── src │ │ │ └── schema.ts │ │ └── drizzle.config.ts │ └── tsconfig.json ├── cloudflare-container │ ├── .gitignore │ ├── container_src │ │ └── go.mod │ ├── types │ │ └── env.d.ts │ ├── Dockerfile │ ├── tsconfig.json │ └── package.json ├── cloudflare-orange │ ├── README.md │ ├── app │ │ ├── root.css │ │ ├── entry.client.ts │ │ ├── entry.server.ts │ │ ├── env.ts │ │ └── routes │ │ │ └── _index.tsx │ ├── .gitignore │ ├── .npmrc │ ├── tailwind.config.js │ ├── alchemy.run.ts │ └── vite.config.ts ├── cloudflare-worker-simple │ ├── .gitignore │ ├── migrations │ │ └── users.sql │ ├── assets │ │ └── index.html │ ├── src │ │ └── worker2.ts │ ├── types │ │ └── cf.d.ts │ ├── tsconfig.json │ └── package.json ├── cloudflare-worker │ ├── .gitignore │ ├── test-file.txt │ ├── src │ │ ├── env.ts │ │ └── rpc.ts │ ├── tsconfig.json │ └── package.json ├── cloudflare-sveltekit │ ├── .npmrc │ ├── static │ │ ├── favicon.png │ │ └── alchemist.webp │ ├── vite.config.ts │ ├── src │ │ ├── routes │ │ │ └── api │ │ │ │ └── test │ │ │ │ └── env │ │ │ │ └── +server.ts │ │ ├── app.html │ │ ├── app.d.ts │ │ └── env.d.ts │ ├── .gitignore │ └── svelte.config.js ├── cloudflare-vite │ ├── .gitignore │ ├── src │ │ ├── vite-env.d.ts │ │ ├── main.tsx │ │ └── env.d.ts │ ├── vite.config.ts │ ├── tsconfig.json │ └── index.html ├── cloudflare-vite-container │ ├── .gitignore │ ├── container_src │ │ └── go.mod │ ├── src │ │ ├── vite-env.d.ts │ │ ├── main.tsx │ │ └── env.d.ts │ ├── vite.config.ts │ ├── tsconfig.json │ ├── index.html │ └── Dockerfile ├── cloudflare-prisma │ ├── .gitignore │ ├── prisma │ │ └── migrations │ │ │ ├── migration_lock.toml │ │ │ └── 20250724220757_1 │ │ │ └── migration.sql │ ├── types │ │ └── env.d.ts │ └── tsconfig.json ├── cloudflare-bun-spa │ ├── bunfig.toml │ ├── src │ │ ├── assets │ │ │ ├── favicon.ico │ │ │ └── potion.png │ │ ├── frontend.tsx │ │ └── index.html │ ├── tsconfig.json │ └── bun-env.d.ts ├── cloudflare-nuxt-pipeline │ ├── public │ │ ├── robots.txt │ │ └── favicon.ico │ ├── app.vue │ ├── server │ │ └── tsconfig.json │ ├── .gitignore │ ├── tsconfig.json │ └── nuxt.config.ts ├── cloudflare-redwood │ ├── src │ │ ├── client.tsx │ │ ├── app │ │ │ ├── shared │ │ │ │ └── links.ts │ │ │ ├── pages │ │ │ │ └── Home.tsx │ │ │ └── Document.tsx │ │ └── db │ │ │ ├── schema.ts │ │ │ └── seed.ts │ ├── types │ │ ├── vite.d.ts │ │ ├── rw.d.ts │ │ └── env.d.ts │ ├── public │ │ └── images │ │ │ ├── new-db.png │ │ │ ├── cloudflare-d1.png │ │ │ ├── cloudflare-new-token.png │ │ │ ├── cloudflare-account-id.png │ │ │ ├── cloudflare-copy-token.png │ │ │ ├── cloudflare-custom-tokens.png │ │ │ ├── cloudflare-token-summary.png │ │ │ └── cloudflare-user-api-tokens.png │ ├── .env.example │ ├── .prettierrc │ ├── vite.config.mts │ ├── drizzle │ │ ├── 0000_lame_kitty_pryde.sql │ │ └── meta │ │ │ └── _journal.json │ └── drizzle.config.ts ├── aws-app │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── package.json ├── cloudflare-tanstack-start │ ├── public │ │ ├── robots.txt │ │ ├── favicon.ico │ │ ├── logo192.png │ │ ├── logo512.png │ │ └── manifest.json │ ├── .gitignore │ ├── .vscode │ │ └── settings.json │ ├── .cta.json │ └── src │ │ ├── router.tsx │ │ ├── env.d.ts │ │ ├── routes │ │ ├── api.demo-names.ts │ │ └── api.test.env.ts │ │ └── styles.css ├── cloudflare-livestore │ ├── src │ │ ├── ambient.d.ts │ │ ├── types.ts │ │ ├── livestore │ │ │ ├── queries.ts │ │ │ ├── schema.ts │ │ │ ├── worker.ts │ │ │ └── server.ts │ │ ├── main.tsx │ │ └── util │ │ │ └── store-id.ts │ ├── vite.config.ts │ └── index.html ├── cloudflare-nextjs │ ├── src │ │ └── app │ │ │ ├── favicon.ico │ │ │ ├── api │ │ │ └── kv │ │ │ │ └── route.ts │ │ │ └── globals.css │ ├── postcss.config.mjs │ ├── public │ │ ├── vercel.svg │ │ ├── _headers │ │ ├── file.svg │ │ └── window.svg │ ├── env.d.ts │ ├── next.config.ts │ ├── open-next.config.ts │ └── alchemy.run.ts ├── cloudflare-react-router │ ├── public │ │ └── favicon.ico │ ├── app │ │ ├── routes.ts │ │ ├── app.css │ │ └── routes │ │ │ └── home.tsx │ ├── react-router.config.ts │ ├── wrangler.jsonc │ ├── .gitignore │ ├── workers │ │ ├── env.ts │ │ └── app.ts │ ├── tsconfig.node.json │ ├── tsconfig.json │ ├── alchemy.run.ts │ └── vite.config.ts ├── prisma-postgres │ ├── tsconfig.json │ └── package.json ├── planetscale-postgres │ ├── drizzle.config.ts │ ├── drizzle │ │ ├── meta │ │ │ └── _journal.json │ │ └── 0000_closed_goblin_queen.sql │ ├── src │ │ └── schema.ts │ ├── env.d.ts │ └── tsconfig.json ├── cloudflare-worker-loader │ ├── src │ │ └── env.ts │ ├── tsconfig.json │ ├── package.json │ └── alchemy.run.ts └── cloudflare-durable-object-websocket │ ├── types │ └── cf.d.ts │ └── tsconfig.json ├── alchemy ├── templates │ ├── hono │ │ ├── _env │ │ ├── _env.example │ │ ├── tsconfig.json │ │ ├── src │ │ │ └── index.ts │ │ ├── alchemy.run.ts │ │ ├── package.json │ │ ├── types │ │ │ └── env.d.ts │ │ ├── .gitignore │ │ ├── _gitignore │ │ └── README.md │ ├── nuxt │ │ ├── _env │ │ ├── _env.example │ │ ├── public │ │ │ ├── robots.txt │ │ │ └── favicon.ico │ │ ├── server │ │ │ ├── tsconfig.json │ │ │ ├── api │ │ │ │ └── hello.ts │ │ │ └── middleware │ │ │ │ ├── auth.ts │ │ │ │ └── hello.ts │ │ ├── app.vue │ │ ├── alchemy.run.ts │ │ ├── .gitignore │ │ ├── _gitignore │ │ ├── tsconfig.json │ │ └── nuxt.config.ts │ ├── vite │ │ ├── _env │ │ ├── _env.example │ │ ├── src │ │ │ ├── vite-env.d.ts │ │ │ ├── main.tsx │ │ │ └── worker.ts │ │ ├── vite.config.ts │ │ ├── alchemy.run.ts │ │ ├── .gitignore │ │ ├── _gitignore │ │ ├── index.html │ │ └── types │ │ │ └── env.d.ts │ ├── astro │ │ ├── _env │ │ ├── _env.example │ │ ├── .vscode │ │ │ ├── extensions.json │ │ │ └── launch.json │ │ ├── wrangler.jsonc │ │ ├── astro.config.mjs │ │ ├── alchemy.run.ts │ │ ├── tsconfig.json │ │ ├── .gitignore │ │ ├── _gitignore │ │ ├── src │ │ │ ├── pages │ │ │ │ ├── index.astro │ │ │ │ └── api │ │ │ │ │ └── hello.ts │ │ │ └── layouts │ │ │ │ └── Layout.astro │ │ ├── types │ │ │ └── env.d.ts │ │ └── package.json │ ├── nextjs │ │ ├── _env │ │ ├── _env.example │ │ ├── src │ │ │ └── app │ │ │ │ ├── favicon.ico │ │ │ │ ├── layout.tsx │ │ │ │ └── api │ │ │ │ └── hello │ │ │ │ └── route.ts │ │ ├── open-next.config.ts │ │ ├── next-env.d.ts │ │ ├── next.config.ts │ │ ├── alchemy.run.ts │ │ ├── types │ │ │ └── env.d.ts │ │ └── eslint.config.mjs │ ├── sveltekit │ │ ├── _env │ │ ├── _npmrc │ │ ├── _env.example │ │ ├── src │ │ │ ├── app.css │ │ │ ├── routes │ │ │ │ ├── +layout.svelte │ │ │ │ └── +page.svelte │ │ │ ├── app.d.ts │ │ │ └── app.html │ │ ├── _prettierrc │ │ ├── static │ │ │ └── favicon.png │ │ ├── vite.config.ts │ │ ├── alchemy.run.ts │ │ ├── svelte.config.js │ │ ├── .gitignore │ │ ├── _gitignore │ │ └── types │ │ │ └── env.d.ts │ ├── bun-spa │ │ ├── _env │ │ ├── _env.example │ │ ├── bunfig.toml │ │ ├── src │ │ │ ├── frontend.tsx │ │ │ └── index.html │ │ ├── _gitignore │ │ ├── tsconfig.json │ │ ├── alchemy.run.ts │ │ └── bun-env.d.ts │ ├── react-router │ │ ├── _env │ │ ├── _env.example │ │ ├── .vscode │ │ │ └── settings.json │ │ ├── build │ │ │ ├── server │ │ │ │ └── index.js │ │ │ └── client │ │ │ │ └── favicon.ico │ │ ├── public │ │ │ └── favicon.ico │ │ ├── app │ │ │ ├── routes.ts │ │ │ ├── app.css │ │ │ └── routes │ │ │ │ └── home.tsx │ │ ├── react-router.config.ts │ │ ├── .gitignore │ │ ├── _gitignore │ │ ├── alchemy.run.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── types │ │ │ └── env.d.ts │ │ ├── vite.config.ts │ │ └── workers │ │ │ └── app.ts │ ├── tanstack-start │ │ ├── _env │ │ ├── _env.example │ │ ├── public │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ └── manifest.json │ │ ├── _gitignore │ │ ├── .vscode │ │ │ └── settings.json │ │ ├── .cta.json │ │ ├── src │ │ │ ├── router.tsx │ │ │ ├── routes │ │ │ │ └── api.demo-names.ts │ │ │ └── styles.css │ │ ├── alchemy.run.ts │ │ └── types │ │ │ └── env.d.ts │ ├── typescript │ │ ├── _env │ │ ├── _env.example │ │ ├── src │ │ │ └── worker.ts │ │ ├── alchemy.run.ts │ │ ├── README.md │ │ ├── types │ │ │ └── env.d.ts │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── .gitignore │ │ └── _gitignore │ └── rwsdk │ │ ├── _dev.vars │ │ ├── src │ │ ├── client.tsx │ │ ├── app │ │ │ ├── shared │ │ │ │ └── links.ts │ │ │ ├── pages │ │ │ │ ├── Home.tsx │ │ │ │ └── user │ │ │ │ │ └── routes.ts │ │ │ └── Document.tsx │ │ ├── session │ │ │ └── store.ts │ │ └── scripts │ │ │ └── seed.ts │ │ ├── .wrangler │ │ ├── deploy │ │ │ └── config.json │ │ └── state │ │ │ └── v3 │ │ │ └── d1 │ │ │ └── miniflare-D1DatabaseObject │ │ │ ├── 3c9b7a410a5e3e208752e4babd46de3306095336020e6da15b297e2fa03b7512.sqlite-shm │ │ │ └── 3c9b7a410a5e3e208752e4babd46de3306095336020e6da15b297e2fa03b7512.sqlite-wal │ │ ├── types │ │ ├── vite.d.ts │ │ ├── rw.d.ts │ │ └── env.d.ts │ │ ├── .devcontainer │ │ └── Dockerfile │ │ ├── vite.config.mts │ │ ├── _env │ │ └── _env.example ├── src │ ├── os │ │ └── index.ts │ ├── esbuild │ │ └── index.ts │ ├── util │ │ ├── index.ts │ │ ├── root-dir.ts │ │ ├── slugify.ts │ │ ├── assert-never.ts │ │ ├── sha256.ts │ │ ├── exists.ts │ │ ├── xml.ts │ │ ├── rm.ts │ │ ├── is-transient-error.ts │ │ ├── sleep.ts │ │ ├── cli-args.ts │ │ ├── detect-node-runtime.ts │ │ ├── diff.ts │ │ ├── ignore.ts │ │ ├── validate-resource-id.ts │ │ ├── nanoid.ts │ │ ├── logger.ts │ │ └── deferred-promise.ts │ ├── random │ │ └── index.ts │ ├── cloudflare │ │ ├── bun-spa │ │ │ └── index.ts │ │ ├── response.ts │ │ ├── worker-loader.ts │ │ ├── compatibility-date.gen.ts │ │ ├── tanstack-start │ │ │ └── plugin.ts │ │ ├── browser-rendering.ts │ │ ├── bundle │ │ │ ├── plugin-als-external.ts │ │ │ └── nodejs-builtin-modules.ts │ │ ├── astro │ │ │ └── plugin.ts │ │ └── react-router │ │ │ └── plugin.ts │ ├── dns │ │ └── index.ts │ ├── aws │ │ ├── oidc │ │ │ └── index.ts │ │ ├── control │ │ │ └── index.ts │ │ ├── ec2 │ │ │ └── index.ts │ │ ├── index.ts │ │ └── account-id.ts │ ├── neon │ │ └── index.ts │ ├── upstash │ │ └── index.ts │ ├── vercel │ │ └── index.ts │ ├── clickhouse │ │ └── index.ts │ ├── coinbase │ │ └── index.ts │ ├── sentry │ │ └── index.ts │ ├── prisma-postgres │ │ └── index.ts │ ├── github │ │ └── index.ts │ ├── fs │ │ ├── index.ts │ │ ├── file-system-state-store.ts │ │ ├── file-ref.ts │ │ └── file-collection.ts │ ├── state │ │ ├── migrations.ts │ │ └── index.ts │ ├── docker │ │ └── index.ts │ ├── planetscale │ │ ├── index.ts │ │ └── organization.ts │ ├── build-date.ts │ ├── type.ts │ ├── index.ts │ ├── stripe │ │ └── index.ts │ └── llms.ts ├── test │ ├── cloudflare │ │ ├── container │ │ │ ├── Dockerfile │ │ │ └── Dockerfile.update │ │ ├── nobundle │ │ │ ├── dir │ │ │ │ └── bar.js │ │ │ ├── foo.js │ │ │ └── index.js │ │ ├── migrations │ │ │ └── 001_create_table.sql │ │ ├── test-handlers │ │ │ ├── basic-fetch.ts │ │ │ ├── tail-handler.ts │ │ │ ├── cojson-wasm.ts │ │ │ ├── workos.ts │ │ │ ├── async-hooks-handler.ts │ │ │ └── node-imports-handler.ts │ │ ├── bundle-handler-als.ts │ │ ├── unenv-handler.ts │ │ ├── images-handler.ts │ │ ├── version-metadata-handler.ts │ │ ├── fetch-utils.ts │ │ ├── test-helpers.ts │ │ └── bundle-handler.ts │ ├── docker │ │ └── fixtures │ │ │ ├── simple-image │ │ │ └── Dockerfile │ │ │ ├── build-args │ │ │ └── Dockerfile │ │ │ └── multi-stage │ │ │ └── Dockerfile │ ├── run.ts │ └── handler.ts ├── .gitignore ├── drizzle │ ├── durable-object │ │ ├── migrations.js │ │ ├── meta │ │ │ └── _journal.json │ │ └── 0000_far_moon_knight.sql │ └── default │ │ ├── meta │ │ └── _journal.json │ │ └── 0000_busy_mauler.sql ├── tsconfig.workers.json ├── scripts │ └── drizzle-generate.ts ├── tsconfig.test.json ├── bin │ ├── services │ │ └── get-package-version.ts │ ├── errors.ts │ └── commands │ │ ├── destroy.ts │ │ ├── deploy.ts │ │ └── run.ts └── tsconfig.json ├── bunfig.toml ├── example-monorepo ├── .env.example ├── .gitignore ├── apps │ ├── frontend │ │ ├── src │ │ │ ├── vite-env.d.ts │ │ │ ├── main.tsx │ │ │ └── worker.ts │ │ ├── vite.config.ts │ │ ├── index.html │ │ ├── alchemy.run.ts │ │ └── types │ │ │ └── env.d.ts │ ├── backend │ │ ├── src │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── alchemy.run.ts │ │ └── package.json │ └── analytics │ │ ├── src │ │ └── index.ts │ │ ├── tsconfig.json │ │ ├── alchemy.run.ts │ │ └── package.json ├── tsconfig.json └── turbo.json ├── tests └── smoke-test-flatten-website │ ├── .env.example │ ├── src │ ├── vite-env.d.ts │ ├── main.tsx │ └── do.ts │ ├── vite.config.ts │ ├── .gitignore │ ├── index.html │ └── types │ └── env.d.ts ├── alchemy-web ├── .gitignore ├── public │ ├── potion.png │ ├── robots.txt │ ├── alchemist.webp │ ├── alchemy-og.png │ ├── turborepo-dev.png │ ├── alchemy-flower.png │ ├── potion-with-border.png │ ├── turborepo-deploy.png │ ├── turborepo-destroy.png │ └── sqlite-state-store.jpeg ├── src │ ├── styles │ │ └── global.css │ ├── env.d.ts │ ├── pages │ │ ├── auth │ │ │ ├── error.astro │ │ │ └── success.astro │ │ └── cloudflare │ │ │ └── auth │ │ │ ├── logout.astro │ │ │ └── callback.astro │ ├── components │ │ ├── ThemeSelect.astro │ │ └── MarkdownContent.astro │ ├── content.config.ts │ └── content │ │ └── docs │ │ └── index.md └── tsconfig.json ├── public ├── alchemist.png └── alchemist.webp ├── stacks ├── package.json └── tsconfig.json ├── .gitattributes ├── .zed └── settings.json ├── scripts ├── gh ├── feat ├── shell.ts ├── generate-pnpm-workspace.yaml.ts ├── test-monorepo.sh └── clients │ └── utils.ts ├── .oxfmtrc.json ├── vitest.setup.ts ├── .gitignore └── .cursor └── rules └── cloudflare.mdc /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /CLAUDE.md: -------------------------------------------------------------------------------- 1 | AGENTS.md -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | **/*.ts -------------------------------------------------------------------------------- /examples/docker/.gitignore: -------------------------------------------------------------------------------- 1 | !.env 2 | -------------------------------------------------------------------------------- /examples/cloudflare-astro/.gitignore: -------------------------------------------------------------------------------- 1 | .astro -------------------------------------------------------------------------------- /examples/planetscale-drizzle/.gitignore: -------------------------------------------------------------------------------- 1 | .alchemy/ -------------------------------------------------------------------------------- /alchemy/templates/hono/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/nuxt/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/vite/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /bunfig.toml: -------------------------------------------------------------------------------- 1 | [install] 2 | linker = "isolated" 3 | -------------------------------------------------------------------------------- /examples/cloudflare-container/.gitignore: -------------------------------------------------------------------------------- 1 | .alchemy/ -------------------------------------------------------------------------------- /examples/cloudflare-orange/README.md: -------------------------------------------------------------------------------- 1 | # orange-template -------------------------------------------------------------------------------- /examples/cloudflare-worker-simple/.gitignore: -------------------------------------------------------------------------------- 1 | .alchemy/ -------------------------------------------------------------------------------- /examples/cloudflare-worker/.gitignore: -------------------------------------------------------------------------------- 1 | wrangler.jsonc -------------------------------------------------------------------------------- /examples/cloudflare-worker/test-file.txt: -------------------------------------------------------------------------------- 1 | some data -------------------------------------------------------------------------------- /alchemy/src/os/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./exec.ts"; 2 | -------------------------------------------------------------------------------- /alchemy/templates/astro/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/nextjs/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/_npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /alchemy/src/esbuild/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./bundle.ts"; 2 | -------------------------------------------------------------------------------- /alchemy/src/util/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./safe-fetch.ts"; 2 | -------------------------------------------------------------------------------- /alchemy/templates/astro/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me 2 | -------------------------------------------------------------------------------- /alchemy/templates/hono/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/nextjs/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/nuxt/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/react-router/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/typescript/_env: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/vite/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /examples/cloudflare-orange/app/root.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /examples/cloudflare-vite/.gitignore: -------------------------------------------------------------------------------- 1 | /wrangler.* 2 | /.wrangler -------------------------------------------------------------------------------- /alchemy/src/random/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./random-string.ts"; 2 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/src/app.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | -------------------------------------------------------------------------------- /alchemy/templates/typescript/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /example-monorepo/.env.example: -------------------------------------------------------------------------------- 1 | API_KEY=foo 2 | ALCHEMY_PASSWORD=todo -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me 2 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/_env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/test/cloudflare/container/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-slim 2 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/nobundle/dir/bar.js: -------------------------------------------------------------------------------- 1 | export const bar = "bar"; 2 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/nobundle/foo.js: -------------------------------------------------------------------------------- 1 | export const foo = "foo"; 2 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/.gitignore: -------------------------------------------------------------------------------- 1 | /wrangler.* 2 | /.wrangler -------------------------------------------------------------------------------- /tests/smoke-test-flatten-website/.env.example: -------------------------------------------------------------------------------- 1 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy-web/.gitignore: -------------------------------------------------------------------------------- 1 | .wrangler 2 | .astro 3 | node_modules 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/container/Dockerfile.update: -------------------------------------------------------------------------------- 1 | FROM python:3.12-slim 2 | -------------------------------------------------------------------------------- /example-monorepo/.gitignore: -------------------------------------------------------------------------------- 1 | .alchemy/ 2 | .turbo/ 3 | node_modules/ 4 | lib/ -------------------------------------------------------------------------------- /examples/cloudflare-prisma/.gitignore: -------------------------------------------------------------------------------- 1 | .alchemy/ 2 | /src/generated/prisma 3 | -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/bunfig.toml: -------------------------------------------------------------------------------- 1 | [serve.static] 2 | env='BUN_PUBLIC_*' 3 | -------------------------------------------------------------------------------- /alchemy/templates/vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/bunfig.toml: -------------------------------------------------------------------------------- 1 | [serve.static] 2 | env='BUN_PUBLIC_*' 3 | -------------------------------------------------------------------------------- /examples/cloudflare-container/container_src/go.mod: -------------------------------------------------------------------------------- 1 | module server 2 | 3 | go 1.24.3 -------------------------------------------------------------------------------- /examples/cloudflare-nuxt-pipeline/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-Agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/bun-spa/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./get-bun-spa-backend.ts"; 2 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/container_src/go.mod: -------------------------------------------------------------------------------- 1 | module server 2 | 3 | go 1.24.3 -------------------------------------------------------------------------------- /examples/cloudflare-vite/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example-monorepo/apps/frontend/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /examples/cloudflare-nuxt-pipeline/app.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /public/alchemist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/public/alchemist.png -------------------------------------------------------------------------------- /public/alchemist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/public/alchemist.webp -------------------------------------------------------------------------------- /tests/smoke-test-flatten-website/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /alchemy/src/dns/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./import-dns.ts"; 2 | export * from "./record.ts"; 3 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/_dev.vars: -------------------------------------------------------------------------------- 1 | /home/aman/dev/work/alchemy/alchemy/templates/my-alchemy-app/.env -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /alchemy/src/util/root-dir.ts: -------------------------------------------------------------------------------- 1 | export const ALCHEMY_ROOT = process.env.ALCHEMY_ROOT ?? process.cwd(); 2 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/_prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": ["prettier-plugin-tailwindcss"] 3 | } 4 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/src/client.tsx: -------------------------------------------------------------------------------- 1 | import { initClient } from "rwsdk/client"; 2 | 3 | initClient(); 4 | -------------------------------------------------------------------------------- /alchemy-web/public/potion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/potion.png -------------------------------------------------------------------------------- /alchemy-web/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: / 3 | 4 | Sitemap: https://alchemy.run/sitemap-index.xml -------------------------------------------------------------------------------- /examples/cloudflare-redwood/src/client.tsx: -------------------------------------------------------------------------------- 1 | import { initClient } from "rwsdk/client"; 2 | 3 | initClient(); 4 | -------------------------------------------------------------------------------- /alchemy-web/public/alchemist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/alchemist.webp -------------------------------------------------------------------------------- /alchemy-web/public/alchemy-og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/alchemy-og.png -------------------------------------------------------------------------------- /alchemy/.gitignore: -------------------------------------------------------------------------------- 1 | bin/alchemy.js 2 | !templates/**/wrangler.jsonc 3 | .nuxt 4 | workers/*.js 5 | bin/external-*.js -------------------------------------------------------------------------------- /alchemy/src/aws/oidc/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./github-oidc-provider.ts"; 2 | export * from "./oidc-provider.ts"; 3 | -------------------------------------------------------------------------------- /alchemy/test/docker/fixtures/simple-image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | CMD ["echo", "Hello from Alchemy!"] 3 | -------------------------------------------------------------------------------- /examples/cloudflare-nuxt-pipeline/server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../.nuxt/tsconfig.server.json" 3 | } 4 | -------------------------------------------------------------------------------- /alchemy-web/public/turborepo-dev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/turborepo-dev.png -------------------------------------------------------------------------------- /alchemy/src/neon/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api.ts"; 2 | export * from "./branch.ts"; 3 | export * from "./project.ts"; 4 | -------------------------------------------------------------------------------- /alchemy/src/upstash/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api.ts"; 2 | export * from "./error.ts"; 3 | export * from "./redis.ts"; 4 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/.wrangler/deploy/config.json: -------------------------------------------------------------------------------- 1 | {"configPath":"../../dist/worker/wrangler.json","auxiliaryWorkers":[]} -------------------------------------------------------------------------------- /examples/cloudflare-orange/app/entry.client.ts: -------------------------------------------------------------------------------- 1 | import { hydrate } from "@orange-js/orange/client"; 2 | 3 | hydrate(); 4 | -------------------------------------------------------------------------------- /examples/docker/.env: -------------------------------------------------------------------------------- 1 | mongoHost=mongodb://mongo:27017 2 | database=cart 3 | nodeEnvironment=development 4 | protocol=http:// -------------------------------------------------------------------------------- /alchemy-web/public/alchemy-flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/alchemy-flower.png -------------------------------------------------------------------------------- /alchemy/templates/react-router/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "wrangler.json": "jsonc" 4 | } 5 | } -------------------------------------------------------------------------------- /examples/cloudflare-orange/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules 3 | .wrangler 4 | .dev.vars 5 | .env 6 | wrangler.jsonc 7 | .types -------------------------------------------------------------------------------- /alchemy-web/public/potion-with-border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/potion-with-border.png -------------------------------------------------------------------------------- /alchemy-web/public/turborepo-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/turborepo-deploy.png -------------------------------------------------------------------------------- /alchemy-web/public/turborepo-destroy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/turborepo-destroy.png -------------------------------------------------------------------------------- /alchemy/src/vercel/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api.ts"; 2 | export * from "./project-domain.ts"; 3 | export * from "./project.ts"; 4 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/nuxt/public/favicon.ico -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/types/vite.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*?url" { 2 | const result: string; 3 | export default result; 4 | } 5 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/aws-app/src/index.ts: -------------------------------------------------------------------------------- 1 | export function handler(_event: any, _context: any) { 2 | console.log("Hello, World!"); 3 | } 4 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /alchemy-web/public/sqlite-state-store.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy-web/public/sqlite-state-store.jpeg -------------------------------------------------------------------------------- /alchemy/src/clickhouse/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api-key.ts"; 2 | export * from "./organization.ts"; 3 | export * from "./service.ts"; 4 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/ambient.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/types/vite.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*?url" { 2 | const result: string; 3 | export default result; 4 | } 5 | -------------------------------------------------------------------------------- /alchemy/src/coinbase/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./types.ts"; 2 | export * from "./evm-account.ts"; 3 | export * from "./evm-smart-account.ts"; 4 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/nextjs/src/app/favicon.ico -------------------------------------------------------------------------------- /alchemy/templates/nuxt/app.vue: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/build/server/index.js: -------------------------------------------------------------------------------- 1 | import { d } from "./assets/app-BR94Nnwe.js"; 2 | export { 3 | d as default 4 | }; 5 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/sveltekit/static/favicon.png -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-nextjs/src/app/favicon.ico -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/src/app/shared/links.ts: -------------------------------------------------------------------------------- 1 | import { defineLinks } from "rwsdk/router"; 2 | 3 | export const link = defineLinks(["/"]); 4 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-sveltekit/static/favicon.png -------------------------------------------------------------------------------- /alchemy/templates/astro/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["astro-build.astro-vscode"], 3 | "unwantedRecommendations": [] 4 | } 5 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/react-router/public/favicon.ico -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/tanstack-start/public/favicon.ico -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/tanstack-start/public/logo192.png -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/tanstack-start/public/logo512.png -------------------------------------------------------------------------------- /alchemy/test/cloudflare/migrations/001_create_table.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE test_migrations_table ( 2 | id INTEGER PRIMARY KEY, 3 | name TEXT 4 | ); 5 | -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/src/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-bun-spa/src/assets/favicon.ico -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/src/assets/potion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-bun-spa/src/assets/potion.png -------------------------------------------------------------------------------- /examples/cloudflare-react-router/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-react-router/public/favicon.ico -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/static/alchemist.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-sveltekit/static/alchemist.webp -------------------------------------------------------------------------------- /alchemy/test/cloudflare/test-handlers/basic-fetch.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | async fetch() { 3 | return new Response("Hello, world!"); 4 | }, 5 | }; 6 | -------------------------------------------------------------------------------- /examples/cloudflare-nuxt-pipeline/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-nuxt-pipeline/public/favicon.ico -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/new-db.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/new-db.png -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-tanstack-start/public/favicon.ico -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-tanstack-start/public/logo192.png -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-tanstack-start/public/logo512.png -------------------------------------------------------------------------------- /alchemy/src/sentry/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api.ts"; 2 | export * from "./client-key.ts"; 3 | export * from "./project.ts"; 4 | export * from "./team.ts"; 5 | -------------------------------------------------------------------------------- /alchemy/src/util/slugify.ts: -------------------------------------------------------------------------------- 1 | export function slugify(str: string, delimiter = "-") { 2 | return str.toLowerCase().replace(/[^a-z0-9]/gi, delimiter); 3 | } 4 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/build/client/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/react-router/build/client/favicon.ico -------------------------------------------------------------------------------- /examples/cloudflare-redwood/.env.example: -------------------------------------------------------------------------------- 1 | CLOUDFLARE_ACCOUNT_ID=__change_me__ 2 | CLOUDFLARE_DATABASE_ID=__change_me__ 3 | CLOUDFLARE_D1_TOKEN=__change_me__ 4 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/.npmrc: -------------------------------------------------------------------------------- 1 | # Bug with resolving dependencies with PNPM + Vite, 2 | # this will be fixed in future versions of Orange 3 | shamefully-hoist = true -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-d1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-d1.png -------------------------------------------------------------------------------- /alchemy/src/prisma-postgres/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./connection.ts"; 2 | export * from "./database.ts"; 3 | export * from "./project.ts"; 4 | export * from "./workspace.ts"; 5 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/src/app/shared/links.ts: -------------------------------------------------------------------------------- 1 | import { defineLinks } from "rwsdk/router"; 2 | 3 | export const link = defineLinks(["/", "/user/login", "/user/logout"]); 4 | -------------------------------------------------------------------------------- /stacks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "alchemy-stacks", 3 | "version": "0.0.1", 4 | "private": true, 5 | "dependencies": { 6 | "alchemy": "workspace:*" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-new-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-new-token.png -------------------------------------------------------------------------------- /alchemy/src/github/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./comment.ts"; 2 | export * from "./repository-environment.ts"; 3 | export * from "./repository-webhook.ts"; 4 | export * from "./secret.ts"; 5 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/types/rw.d.ts: -------------------------------------------------------------------------------- 1 | import { AppContext } from "../src/worker"; 2 | 3 | declare module "rwsdk/worker" { 4 | interface DefaultAppContext extends AppContext {} 5 | } 6 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 | {@render children()} 8 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/public/_headers: -------------------------------------------------------------------------------- 1 | # https://developers.cloudflare.com/workers/static-assets/headers 2 | /_next/static/* 3 | Cache-Control: public,max-age=31536000,immutable 4 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-account-id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-account-id.png -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-copy-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-copy-token.png -------------------------------------------------------------------------------- /alchemy/src/util/assert-never.ts: -------------------------------------------------------------------------------- 1 | export function assertNever(value: never, message?: string): never { 2 | throw new Error(message ?? `Unexpected value: ${JSON.stringify(value)}`); 3 | } 4 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/app/routes.ts: -------------------------------------------------------------------------------- 1 | import { type RouteConfig, index } from "@react-router/dev/routes"; 2 | 3 | export default [index("routes/home.tsx")] satisfies RouteConfig; 4 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 |

Welcome to SvelteKit

2 |

Visit svelte.dev/docs/kit to read the documentation

3 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/app/routes.ts: -------------------------------------------------------------------------------- 1 | import { type RouteConfig, index } from "@react-router/dev/routes"; 2 | 3 | export default [index("routes/home.tsx")] satisfies RouteConfig; 4 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-custom-tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-custom-tokens.png -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-token-summary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-token-summary.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.astro linguist-vendored 2 | *.css linguist-vendored 3 | *.js linguist-vendored 4 | *.mdx linguist-vendored 5 | Dockerfile linguist-vendored 6 | Dockerfile.* linguist-vendored 7 | -------------------------------------------------------------------------------- /alchemy/src/util/sha256.ts: -------------------------------------------------------------------------------- 1 | import { createHash } from "node:crypto"; 2 | 3 | export function sha256(value: string): string { 4 | return createHash("sha256").update(value).digest("hex"); 5 | } 6 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/public/images/cloudflare-user-api-tokens.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/examples/cloudflare-redwood/public/images/cloudflare-user-api-tokens.png -------------------------------------------------------------------------------- /alchemy/src/aws/control/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./client.ts"; 2 | export * from "./proxy.ts"; 3 | export * from "./resource.ts"; 4 | import { AWS } from "./proxy.ts"; 5 | 6 | export default AWS; 7 | -------------------------------------------------------------------------------- /alchemy/src/fs/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./copy-file.ts"; 2 | export * from "./file-collection.ts"; 3 | export * from "./file-ref.ts"; 4 | export * from "./file.ts"; 5 | export * from "./folder.ts"; 6 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/test-handlers/tail-handler.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | async tail(events: any[]) { 3 | for (const event of events) { 4 | console.log(event); 5 | } 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /examples/cloudflare-prisma/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (e.g., Git) 3 | provider = "sqlite" 4 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm 2 | 3 | EXPOSE 5713 4 | 5 | RUN corepack enable 6 | COPY . /app 7 | WORKDIR /app 8 | 9 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/vite.config.mts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy/cloudflare/redwood"; 2 | import { defineConfig } from "vite"; 3 | 4 | export default defineConfig({ 5 | plugins: [alchemy()], 6 | }); 7 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from "@sveltejs/kit/vite"; 2 | import { defineConfig } from "vite"; 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()], 6 | }); 7 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "overrides": [ 3 | { 4 | "files": "*.jsonc", 5 | "options": { 6 | "trailingComma": "none" 7 | } 8 | } 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | count.txt 7 | .env 8 | .nitro 9 | .tanstack 10 | .output 11 | .vinxi 12 | todos.json 13 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/types.ts: -------------------------------------------------------------------------------- 1 | import { Schema } from "@livestore/livestore"; 2 | 3 | export const Filter = Schema.Literal("all", "active", "completed"); 4 | export type Filter = typeof Filter.Type; 5 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from "@sveltejs/kit/vite"; 2 | import { defineConfig } from "vite"; 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()], 6 | }); 7 | -------------------------------------------------------------------------------- /examples/prisma-postgres/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "outDir": "dist", 5 | "rootDir": "." 6 | }, 7 | "include": ["./alchemy.run.ts"] 8 | } 9 | -------------------------------------------------------------------------------- /alchemy/src/state/migrations.ts: -------------------------------------------------------------------------------- 1 | import path from "pathe"; 2 | 3 | export const MIGRATIONS_DIRECTORY = path.join( 4 | import.meta.dirname, 5 | "..", 6 | "..", 7 | "drizzle", 8 | "default", 9 | ); 10 | -------------------------------------------------------------------------------- /alchemy/templates/astro/wrangler.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "main": "dist/_worker.js/index.js", 4 | "compatibility_date": "2025-04-20", 5 | "assets": { "binding": "ASSETS", "directory": "dist" } 6 | } 7 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/open-next.config.ts: -------------------------------------------------------------------------------- 1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare"; 2 | 3 | export default defineCloudflareConfig({ 4 | // Configure OpenNext for Cloudflare Workers 5 | }); 6 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/server/api/hello.ts: -------------------------------------------------------------------------------- 1 | // see: https://nuxt.com/docs/guide/directory-structure/server 2 | 3 | export default defineEventHandler((event) => { 4 | return { 5 | hello: "world", 6 | }; 7 | }); 8 | -------------------------------------------------------------------------------- /stacks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "include": ["src/**/*.ts"], 4 | "compilerOptions": { 5 | "noEmit": true 6 | }, 7 | "references": [{ "path": "../alchemy/tsconfig.json" }] 8 | } 9 | -------------------------------------------------------------------------------- /.zed/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "lsp": { 3 | "oxc": { 4 | "settings": { 5 | "run": "onSave", 6 | "fmt.experimental": true, 7 | "fmt.configPath": null 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/src/docker/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api.ts"; 2 | export * from "./remote-image.ts"; 3 | export * from "./container.ts"; 4 | export * from "./network.ts"; 5 | export * from "./volume.ts"; 6 | export * from "./image.ts"; 7 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/_gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | count.txt 7 | .env 8 | .nitro 9 | .tanstack 10 | .output 11 | .vinxi 12 | todos.json 13 | .wrangler 14 | .alchemy -------------------------------------------------------------------------------- /alchemy/test/cloudflare/bundle-handler-als.ts: -------------------------------------------------------------------------------- 1 | import hooks from "node:async_hooks"; 2 | 3 | export default { 4 | async fetch(): Promise { 5 | return new Response(typeof hooks.AsyncLocalStorage); 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/server/middleware/auth.ts: -------------------------------------------------------------------------------- 1 | // see: https://nuxt.com/docs/guide/directory-structure/server#server-middleware 2 | 3 | export default defineEventHandler((event) => { 4 | event.context.auth = { user: 123 }; 5 | }); 6 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/_env: -------------------------------------------------------------------------------- 1 | WEBAUTHN_RP_ID=localhost 2 | AUTH_SECRET_KEY=your-development-secret-key 3 | # Optional: Enable Turnstile bot protection 4 | # TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA 5 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/livestore/queries.ts: -------------------------------------------------------------------------------- 1 | import { queryDb } from "@livestore/livestore"; 2 | 3 | import { tables } from "./tables.ts"; 4 | 5 | export const uiState$ = queryDb(tables.uiState.get(), { label: "uiState" }); 6 | -------------------------------------------------------------------------------- /scripts/gh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [[ "$1" == "pr" && "$2" == "checkout" ]]; then 4 | pr=$3 5 | git worktree add ../alchemy-$pr 6 | cd ../alchemy-$pr 7 | gh pr checkout $pr 8 | cp ../.env . 9 | bun i 10 | cursor . 11 | fi -------------------------------------------------------------------------------- /alchemy-web/src/styles/global.css: -------------------------------------------------------------------------------- 1 | @layer base, starlight, theme, components, utilities; 2 | 3 | @import '@astrojs/starlight-tailwind'; 4 | @import 'tailwindcss/theme.css' layer(theme); 5 | @import 'tailwindcss/utilities.css' layer(utilities); 6 | -------------------------------------------------------------------------------- /alchemy/drizzle/durable-object/migrations.js: -------------------------------------------------------------------------------- 1 | import journal from "./meta/_journal.json"; 2 | import m0000 from "./0000_far_moon_knight.sql"; 3 | 4 | export default { 5 | journal, 6 | migrations: { 7 | m0000, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/react-router.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "@react-router/dev/config"; 2 | 3 | export default { 4 | ssr: true, 5 | future: { 6 | unstable_viteEnvironmentApi: true, 7 | }, 8 | } satisfies Config; 9 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: ["./index.html", "./app/**/*.{js,ts,jsx,tsx}"], 4 | theme: { 5 | extend: {}, 6 | }, 7 | plugins: [], 8 | }; 9 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/vite.config.mts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy/cloudflare/redwood"; 2 | import { defineConfig, type PluginOption } from "vite"; 3 | 4 | export default defineConfig({ 5 | plugins: [alchemy() as PluginOption], 6 | }); 7 | -------------------------------------------------------------------------------- /alchemy-web/src/env.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace App { 2 | type StarlightLocals = import("@astrojs/starlight").StarlightLocals; 3 | // Define the `locals.t` object in the context of a plugin. 4 | interface Locals extends StarlightLocals {} 5 | } 6 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/_env.example: -------------------------------------------------------------------------------- 1 | WEBAUTHN_RP_ID=localhost 2 | AUTH_SECRET_KEY=your-development-secret-key 3 | # Optional: Enable Turnstile bot protection 4 | # TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA 5 | ALCHEMY_PASSWORD=change-me -------------------------------------------------------------------------------- /alchemy/test/cloudflare/test-handlers/cojson-wasm.ts: -------------------------------------------------------------------------------- 1 | import { initialize } from "cojson-core-wasm/edge-lite"; 2 | 3 | export default { 4 | async fetch() { 5 | await initialize(); 6 | return new Response("Hello, world!"); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/react-router.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from "@react-router/dev/config"; 2 | 3 | export default { 4 | ssr: true, 5 | future: { 6 | unstable_viteEnvironmentApi: true, 7 | }, 8 | } satisfies Config; 9 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/server/middleware/hello.ts: -------------------------------------------------------------------------------- 1 | // see: https://nuxt.com/docs/guide/directory-structure/server#server-middleware 2 | 3 | export default defineEventHandler((event) => { 4 | console.log("New request: " + getRequestURL(event)); 5 | }); 6 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/app/entry.server.ts: -------------------------------------------------------------------------------- 1 | import { app } from "@orange-js/orange/server"; 2 | import * as serverBuild from "virtual:orange/server-bundle"; 3 | 4 | export * from "virtual:orange/entrypoints"; 5 | 6 | export default app(serverBuild); 7 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules/ 3 | *.tsbuildinfo 4 | 5 | # React Router 6 | /.react-router/ 7 | /build/ 8 | 9 | # Cloudflare 10 | .mf 11 | .wrangler 12 | .dev.vars* 13 | 14 | .alchemy/ 15 | .env 16 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/react-router/_gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules/ 3 | *.tsbuildinfo 4 | 5 | # React Router 6 | /.react-router/ 7 | /build/ 8 | 9 | # Cloudflare 10 | .mf 11 | .wrangler 12 | .dev.vars* 13 | 14 | .alchemy/ 15 | .env 16 | .wrangler/ -------------------------------------------------------------------------------- /examples/cloudflare-react-router/wrangler.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-react-router-samgoodwin-website", 3 | "main": "workers/app.ts", 4 | "compatibility_date": "2025-08-02", 5 | "assets": { "directory": "build/client", "binding": "ASSETS" } 6 | } 7 | -------------------------------------------------------------------------------- /scripts/feat: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | NAME=$1 4 | 5 | if [ -z "$NAME" ]; then 6 | echo "Usage: $0 " 7 | exit 1 8 | fi 9 | 10 | git worktree add -b $USER/$NAME ../alchemy-$NAME 11 | cd ../alchemy-$NAME 12 | cp ../.env . 13 | bun i 14 | cursor . -------------------------------------------------------------------------------- /alchemy/src/planetscale/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./api.ts"; 2 | export * from "./branch.ts"; 3 | export * from "./database.ts"; 4 | export * from "./organization.ts"; 5 | export * from "./password.ts"; 6 | export * from "./role.ts"; 7 | export * from "./utils.ts"; 8 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/test-handlers/workos.ts: -------------------------------------------------------------------------------- 1 | import { WorkOS } from "@workos-inc/node"; 2 | 3 | export default { 4 | async fetch() { 5 | new WorkOS("sk_test_1234567890"); 6 | 7 | return new Response(null, { status: 204 }); 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /alchemy/tsconfig.workers.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "include": ["workers/**/*.ts"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "noEmit": true, 7 | "types": ["@cloudflare/workers-types"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-simple/migrations/users.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE IF NOT EXISTS users ( 2 | id INTEGER PRIMARY KEY AUTOINCREMENT, 3 | name TEXT NOT NULL, 4 | email TEXT NOT NULL, 5 | created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL 6 | ); 7 | -------------------------------------------------------------------------------- /alchemy/src/fs/file-system-state-store.ts: -------------------------------------------------------------------------------- 1 | import * as state from "../state/file-system-state-store.ts"; 2 | 3 | /** 4 | * @deprecated Use `FileSystemStateStore` from `alchemy/state` instead. 5 | */ 6 | export const FileSystemStateStore = state.FileSystemStateStore; 7 | -------------------------------------------------------------------------------- /alchemy/src/util/exists.ts: -------------------------------------------------------------------------------- 1 | import { access } from "node:fs/promises"; 2 | 3 | export async function exists(path: string): Promise { 4 | try { 5 | await access(path); 6 | return true; 7 | } catch { 8 | return false; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /alchemy/src/util/xml.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Extract value from XML string 3 | */ 4 | export function extractXmlValue(xml: string, tagName: string): string { 5 | const match = xml.match(new RegExp(`<${tagName}>(.*?)`)); 6 | return match ? match[1] : ""; 7 | } 8 | -------------------------------------------------------------------------------- /alchemy/templates/astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy/cloudflare/astro"; 2 | import { defineConfig } from "astro/config"; 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | output: "server", 7 | adapter: alchemy(), 8 | }); 9 | -------------------------------------------------------------------------------- /example-monorepo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { 5 | "path": "./apps/backend" 6 | }, 7 | { 8 | "path": "./apps/analytics" 9 | }, 10 | { 11 | "path": "./apps/frontend" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /examples/cloudflare-astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy/cloudflare/astro"; 2 | import { defineConfig } from "astro/config"; 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | output: "server", 7 | adapter: alchemy(), 8 | }); 9 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/response.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Cloudflare API response format 3 | */ 4 | export interface CloudflareResponse { 5 | result: T; 6 | success: boolean; 7 | errors: Array<{ code: number; message: string }>; 8 | messages: string[]; 9 | } 10 | -------------------------------------------------------------------------------- /.oxfmtrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": false, 4 | "tabWidth": 2, 5 | "useTabs": false, 6 | "printWidth": 80, 7 | "endOfLine": "lf", 8 | "experimentalTernaries": true, 9 | "experimental_sort_imports": { 10 | "order": "asc" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /alchemy/templates/vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import alchemy from "alchemy/cloudflare/vite"; 3 | import { defineConfig } from "vite"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), alchemy()], 8 | }); 9 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/src/app/api/kv/route.ts: -------------------------------------------------------------------------------- 1 | import { getCloudflareContext } from "@opennextjs/cloudflare"; 2 | 3 | export const GET = async () => { 4 | const { env } = getCloudflareContext(); 5 | const values = await env.KV.list(); 6 | return Response.json(values); 7 | }; 8 | -------------------------------------------------------------------------------- /examples/planetscale-drizzle/database/src/schema.ts: -------------------------------------------------------------------------------- 1 | import { mysqlTable, serial, varchar } from "drizzle-orm/mysql-core"; 2 | 3 | export const sampleTable = mysqlTable("sample_table", { 4 | id: serial("id").primaryKey(), 5 | value: varchar("value", { length: 255 }).notNull(), 6 | }); 7 | -------------------------------------------------------------------------------- /alchemy/src/build-date.ts: -------------------------------------------------------------------------------- 1 | // This file is auto-generated during build 2 | // Do not edit manually 3 | 4 | /** 5 | * The build date used as the default worker compatibility date. 6 | * This is set to the date when the package was built. 7 | */ 8 | export const BUILD_DATE = "2025-07-13"; 9 | -------------------------------------------------------------------------------- /examples/cloudflare-astro/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { website } from "../alchemy.run.ts"; 4 | 5 | type CloudflareEnv = typeof website.Env; 6 | 7 | declare namespace App { 8 | interface Locals extends CloudflareEnv {} 9 | } 10 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/drizzle/0000_lame_kitty_pryde.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `users` ( 2 | `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL, 3 | `name` text NOT NULL, 4 | `email` text NOT NULL 5 | ); 6 | --> statement-breakpoint 7 | CREATE UNIQUE INDEX `users_email_unique` ON `users` (`email`); -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/src/routes/api/test/env/+server.ts: -------------------------------------------------------------------------------- 1 | import type { RequestEvent } from "@sveltejs/kit"; 2 | 3 | export const GET = async ({ platform }: RequestEvent) => { 4 | return Response.json({ 5 | ALCHEMY_TEST_VALUE: platform!.env.ALCHEMY_TEST_VALUE, 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /vitest.setup.ts: -------------------------------------------------------------------------------- 1 | import { config } from "dotenv"; 2 | config({ path: ".env", quiet: true }); 3 | 4 | // Polyfill File constructor for Node.js if not available 5 | if (typeof globalThis.File === "undefined") { 6 | const { File } = require("node:buffer"); 7 | globalThis.File = File; 8 | } 9 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/worker-loader.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * A binding for dynamic worker loaders. 3 | * 4 | */ 5 | export type WorkerLoader = { 6 | type: "worker_loader"; 7 | }; 8 | export function WorkerLoader(): WorkerLoader { 9 | return { 10 | type: "worker_loader", 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.watcherExclude": { 3 | "**/routeTree.gen.ts": true 4 | }, 5 | "search.exclude": { 6 | "**/routeTree.gen.ts": true 7 | }, 8 | "files.readonlyInclude": { 9 | "**/routeTree.gen.ts": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/smoke-test-flatten-website/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import alchemy from "alchemy/cloudflare/vite"; 3 | import { defineConfig } from "vite"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), alchemy()], 8 | }); 9 | -------------------------------------------------------------------------------- /alchemy/src/state/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./cloudflare-state-store.ts"; 2 | export * from "./d1-state-store.ts"; 3 | export * from "./dofs-state-store/index.ts"; 4 | export * from "./file-system-state-store.ts"; 5 | export * from "./r2-rest-state-store.ts"; 6 | export * from "./sqlite-state-store.ts"; 7 | -------------------------------------------------------------------------------- /alchemy/templates/astro/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "command": "./node_modules/.bin/astro dev", 6 | "name": "Development server", 7 | "request": "launch", 8 | "type": "node-terminal" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/unenv-handler.ts: -------------------------------------------------------------------------------- 1 | import fs from "node:fs/promises"; 2 | 3 | export default { 4 | async fetch( 5 | _request: Request, 6 | _env: any, 7 | _ctx: ExecutionContext, 8 | ): Promise { 9 | return new Response(typeof fs.readFile); 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.watcherExclude": { 3 | "**/routeTree.gen.ts": true 4 | }, 5 | "search.exclude": { 6 | "**/routeTree.gen.ts": true 7 | }, 8 | "files.readonlyInclude": { 9 | "**/routeTree.gen.ts": true 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/src/util/rm.ts: -------------------------------------------------------------------------------- 1 | import fs from "node:fs/promises"; 2 | 3 | export async function rm(path: string) { 4 | try { 5 | await fs.rm(path, { recursive: true, force: true }); 6 | } catch (error: any) { 7 | if (error.code !== "ENOENT") { 8 | throw error; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/nobundle/index.js: -------------------------------------------------------------------------------- 1 | import { bar } from "./dir/bar.js"; 2 | import { foo } from "./foo.js"; 3 | 4 | export default { 5 | async fetch() { 6 | return new Response( 7 | JSON.stringify({ 8 | foo, 9 | bar, 10 | }), 11 | ); 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /examples/aws-app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src/**/*.ts", "alchemy.run.ts"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "resolveJsonModule": true 7 | }, 8 | "references": [{ "path": "../../alchemy/tsconfig.json" }] 9 | } 10 | -------------------------------------------------------------------------------- /examples/docker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "include": ["src/**/*.ts", "alchemy.run.ts"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "resolveJsonModule": true 7 | }, 8 | "references": [{ "path": "../../alchemy/tsconfig.json" }] 9 | } 10 | -------------------------------------------------------------------------------- /examples/planetscale-postgres/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "drizzle-kit"; 2 | 3 | export default defineConfig({ 4 | out: "./drizzle", 5 | schema: "./src/schema.ts", 6 | dialect: "postgresql", 7 | dbCredentials: { 8 | url: process.env.DATABASE_URL!, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /alchemy/drizzle/durable-object/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7", 3 | "dialect": "sqlite", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "version": "6", 8 | "when": 1752097986271, 9 | "tag": "0000_far_moon_knight", 10 | "breakpoints": true 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /examples/cloudflare-redwood/src/db/schema.ts: -------------------------------------------------------------------------------- 1 | // schema.ts 2 | import { int, sqliteTable, text } from "drizzle-orm/sqlite-core"; 3 | 4 | export const users = sqliteTable("users", { 5 | id: int().primaryKey({ autoIncrement: true }), 6 | name: text().notNull(), 7 | email: text().notNull().unique(), 8 | }); 9 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/types/rw.d.ts: -------------------------------------------------------------------------------- 1 | import { AppContext } from "../src/worker.js"; 2 | 3 | declare module "rwsdk/worker" { 4 | export interface DefaultAppContext extends AppContext {} 5 | export interface RequestInfo { 6 | ctx: AppContext; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /alchemy/templates/vite/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App.tsx"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/env.d.ts: -------------------------------------------------------------------------------- 1 | import type { website } from "./alchemy.run.ts"; 2 | 3 | declare global { 4 | type CloudflareEnv = typeof website.Env; 5 | } 6 | 7 | declare module "cloudflare:workers" { 8 | namespace Cloudflare { 9 | export interface Env extends CloudflareEnv {} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /node_modules/ 3 | *.tsbuildinfo 4 | 5 | # React Router 6 | /.react-router/ 7 | /build/ 8 | 9 | # Cloudflare 10 | .mf 11 | .wrangler 12 | .dev.vars* 13 | 14 | # we include it because it's needed for smoke `react-router typegen` 15 | !wrangler.json* 16 | -------------------------------------------------------------------------------- /examples/cloudflare-vite/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App.tsx"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /alchemy/scripts/drizzle-generate.ts: -------------------------------------------------------------------------------- 1 | import { $ } from "bun"; 2 | 3 | await Promise.all([ 4 | $`drizzle-kit generate --schema src/sqlite/db.ts --out drizzle/default --dialect sqlite`, 5 | $`drizzle-kit generate --schema src/sqlite/db.ts --out drizzle/durable-object --dialect sqlite --driver durable-sqlite`, 6 | ]); 7 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/compatibility-date.gen.ts: -------------------------------------------------------------------------------- 1 | // This file is auto-generated during build 2 | // Do not edit manually 3 | 4 | /** 5 | * The default Cloudflare Workers compatibility date, set based on the latest workerd release at the time of build. 6 | */ 7 | export const DEFAULT_COMPATIBILITY_DATE = "2025-11-19"; 8 | -------------------------------------------------------------------------------- /alchemy/templates/astro/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Astro } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await Astro("website"); 7 | 8 | console.log({ 9 | url: worker.url, 10 | }); 11 | 12 | await app.finalize(); 13 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/next.config.ts: -------------------------------------------------------------------------------- 1 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare"; 2 | import type { NextConfig } from "next"; 3 | 4 | const nextConfig: NextConfig = { 5 | /* config options here */ 6 | }; 7 | 8 | export default nextConfig; 9 | 10 | initOpenNextCloudflareForDev(); 11 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Nuxt } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await Nuxt("website"); 7 | 8 | console.log({ 9 | url: worker.url, 10 | }); 11 | 12 | await app.finalize(); 13 | -------------------------------------------------------------------------------- /examples/aws-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aws-app", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "deploy": "alchemy deploy", 7 | "destroy": "alchemy destroy", 8 | "dev": "alchemy dev" 9 | }, 10 | "dependencies": { 11 | "alchemy": "workspace:*" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/drizzle/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7", 3 | "dialect": "sqlite", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "version": "6", 8 | "when": 1743024718213, 9 | "tag": "0000_lame_kitty_pryde", 10 | "breakpoints": true 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /examples/cloudflare-vite/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import alchemy from "alchemy/cloudflare/vite"; 3 | import { defineConfig, type PluginOption } from "vite"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [alchemy() as PluginOption, react()], 8 | }); 9 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-simple/assets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Document 7 | 8 | 9 |

Hello World

10 | 11 | -------------------------------------------------------------------------------- /alchemy/src/util/is-transient-error.ts: -------------------------------------------------------------------------------- 1 | export function isTransientNetworkError(err: any) { 2 | return ( 3 | err?.code === "UND_ERR_SOCKET" || 4 | err?.code === "ECONNRESET" || 5 | err?.code === "UND_ERR_CONNECT_TIMEOUT" || 6 | err?.code === "EPIPE" || 7 | err?.name === "FetchError" 8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /example-monorepo/apps/frontend/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App.tsx"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /examples/cloudflare-prisma/prisma/migrations/20250724220757_1/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "User" ( 3 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 4 | "email" TEXT NOT NULL, 5 | "name" TEXT 6 | ); 7 | 8 | -- CreateIndex 9 | CREATE UNIQUE INDEX "User_email_key" ON "User"("email"); 10 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App.tsx"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /examples/cloudflare-worker/src/env.ts: -------------------------------------------------------------------------------- 1 | import type { worker } from "../alchemy.run.ts"; 2 | 3 | declare global { 4 | export type CloudflareEnv = typeof worker.Env; 5 | } 6 | 7 | declare module "cloudflare:workers" { 8 | namespace Cloudflare { 9 | export interface Env extends CloudflareEnv {} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/planetscale-postgres/drizzle/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7", 3 | "dialect": "postgresql", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "version": "7", 8 | "when": 1756269595070, 9 | "tag": "0000_closed_goblin_queen", 10 | "breakpoints": true 11 | } 12 | ] 13 | } -------------------------------------------------------------------------------- /tests/smoke-test-flatten-website/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import "./index.css"; 4 | import App from "./App.tsx"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | -------------------------------------------------------------------------------- /example-monorepo/apps/frontend/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import alchemy from "alchemy/cloudflare/vite"; 3 | import { defineConfig, type PluginOption } from "vite"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [react(), alchemy() as PluginOption], 8 | }); 9 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import alchemy from "alchemy/cloudflare/vite"; 3 | import { defineConfig, type PluginOption } from "vite"; 4 | 5 | // https://vite.dev/config/ 6 | export default defineConfig({ 7 | plugins: [alchemy() as PluginOption, react()], 8 | }); 9 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-loader/src/env.ts: -------------------------------------------------------------------------------- 1 | import type { worker } from "../alchemy.run.ts"; 2 | 3 | declare global { 4 | export type CloudflareEnv = typeof worker.Env; 5 | } 6 | 7 | declare module "cloudflare:workers" { 8 | namespace Cloudflare { 9 | export interface Env extends CloudflareEnv {} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { SvelteKit } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await SvelteKit("website"); 7 | 8 | console.log({ 9 | url: worker.url, 10 | }); 11 | 12 | await app.finalize(); 13 | -------------------------------------------------------------------------------- /alchemy/test/docker/fixtures/build-args/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest 2 | 3 | # Define build arguments 4 | ARG MESSAGE=default 5 | ARG VERSION=1.0 6 | 7 | # Use the build arguments 8 | RUN echo "$MESSAGE (version $VERSION)" > /message.txt 9 | 10 | # Display the content when container runs 11 | CMD ["cat", "/message.txt"] 12 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/.cta.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "cloudflare-tanstack-start", 3 | "mode": "file-router", 4 | "typescript": true, 5 | "tailwind": true, 6 | "packageManager": "bun", 7 | "git": true, 8 | "version": 1, 9 | "framework": "react-cra", 10 | "chosenAddOns": [ 11 | "start" 12 | ] 13 | } -------------------------------------------------------------------------------- /examples/planetscale-postgres/drizzle/0000_closed_goblin_queen.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE "users" ( 2 | "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL, 3 | "email" varchar(255) NOT NULL, 4 | "password" varchar(255) NOT NULL, 5 | "createdAt" timestamp DEFAULT now() NOT NULL, 6 | "updatedAt" timestamp DEFAULT now() NOT NULL 7 | ); 8 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/tanstack-start/plugin.ts: -------------------------------------------------------------------------------- 1 | import type { PluginConfig } from "@cloudflare/vite-plugin"; 2 | import alchemyVite from "../vite/plugin.ts"; 3 | 4 | export default function alchemy(options: PluginConfig = {}) { 5 | return alchemyVite({ 6 | viteEnvironment: { name: "ssr" }, 7 | ...options, 8 | }); 9 | } 10 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { ReactRouter } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await ReactRouter("website"); 7 | 8 | console.log({ 9 | url: worker.url, 10 | }); 11 | 12 | await app.finalize(); 13 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/3c9b7a410a5e3e208752e4babd46de3306095336020e6da15b297e2fa03b7512.sqlite-shm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/rwsdk/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/3c9b7a410a5e3e208752e4babd46de3306095336020e6da15b297e2fa03b7512.sqlite-shm -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/3c9b7a410a5e3e208752e4babd46de3306095336020e6da15b297e2fa03b7512.sqlite-wal: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unknown/alchemy/main/alchemy/templates/rwsdk/.wrangler/state/v3/d1/miniflare-D1DatabaseObject/3c9b7a410a5e3e208752e4babd46de3306095336020e6da15b297e2fa03b7512.sqlite-wal -------------------------------------------------------------------------------- /examples/cloudflare-worker/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/*.ts"], 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "types": ["@cloudflare/workers-types"], 6 | "noEmit": true 7 | }, 8 | "references": [ 9 | { 10 | "path": "../../alchemy/tsconfig.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /alchemy/src/util/sleep.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Pauses execution for a specified number of milliseconds. 3 | * @param ms The number of milliseconds to sleep. 4 | * @returns A promise that resolves after the specified time. 5 | */ 6 | export function sleep(ms: number): Promise { 7 | return new Promise((resolve) => setTimeout(resolve, ms)); 8 | } 9 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/.cta.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "@alchemy.run/tanstack-start-template", 3 | "mode": "file-router", 4 | "typescript": true, 5 | "tailwind": true, 6 | "packageManager": "bun", 7 | "git": true, 8 | "version": 1, 9 | "framework": "react-cra", 10 | "chosenAddOns": [ 11 | "start" 12 | ] 13 | } -------------------------------------------------------------------------------- /alchemy/templates/typescript/src/worker.ts: -------------------------------------------------------------------------------- 1 | import type { worker } from "../alchemy.run.ts"; 2 | 3 | export default { 4 | async fetch( 5 | request: Request, 6 | env: typeof worker.Env, 7 | ctx: ExecutionContext, 8 | ): Promise { 9 | return new Response("Hello World from my-alchemy-app!"); 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/cloudflare-vite/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { website } from "../alchemy.run.ts"; 4 | 5 | export type CloudflareEnv = typeof website.Env; 6 | 7 | declare module "cloudflare:workers" { 8 | namespace Cloudflare { 9 | export interface Env extends CloudflareEnv {} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/templates/typescript/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Worker } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await Worker("worker", { 7 | entrypoint: "src/worker.ts", 8 | }); 9 | 10 | console.log(worker.url); 11 | 12 | await app.finalize(); 13 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-loader/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src/*.ts"], 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "types": ["@cloudflare/workers-types"], 6 | "noEmit": true 7 | }, 8 | "references": [ 9 | { 10 | "path": "../../alchemy/tsconfig.json" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /examples/cloudflare-astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "include": [".astro/types.d.ts", "**/*"], 4 | "exclude": ["dist", "alchemy.run.ts"], 5 | "compilerOptions": { 6 | "types": ["astro/client", "@cloudflare/workers-types"] 7 | }, 8 | "references": [{ "path": "../../alchemy/tsconfig.json" }] 9 | } 10 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { website } from "../alchemy.run.ts"; 4 | 5 | export type CloudflareEnv = typeof website.Env; 6 | 7 | declare module "cloudflare:workers" { 8 | namespace Cloudflare { 9 | export interface Env extends CloudflareEnv {} 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/src/util/cli-args.ts: -------------------------------------------------------------------------------- 1 | export const cliArgs = process.argv.slice(2); 2 | 3 | export function parseOption( 4 | option: string, 5 | defaultValue?: D, 6 | ): D { 7 | const i = cliArgs.indexOf(option); 8 | return ( 9 | i !== -1 && i + 1 < cliArgs.length ? cliArgs[i + 1] : defaultValue 10 | ) as D; 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/images-handler.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | async fetch(_request: Request, env: any): Promise { 3 | if (env.IMAGES && env.IMAGES.type === "images") { 4 | return new Response("Images binding available", { status: 200 }); 5 | } 6 | return new Response("Images binding not found", { status: 500 }); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /alchemy/templates/vite/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Vite } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await Vite("website", { 7 | entrypoint: "src/worker.ts", 8 | }); 9 | 10 | console.log({ 11 | url: worker.url, 12 | }); 13 | 14 | await app.finalize(); 15 | -------------------------------------------------------------------------------- /examples/docker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docker", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc -b", 8 | "deploy": "alchemy deploy --env-file ../../.env", 9 | "destroy": "alchemy destroy --env-file ../../.env", 10 | "dev": "alchemy dev --env-file ../../.env" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /alchemy/src/util/detect-node-runtime.ts: -------------------------------------------------------------------------------- 1 | declare var Deno: any; 2 | declare var Bun: any; 3 | 4 | export type Runtime = "bun" | "deno" | "node"; 5 | 6 | export function detectRuntime(): Runtime { 7 | if (typeof Bun !== "undefined" && Bun !== null) return "bun"; 8 | if (typeof Deno !== "undefined" && Deno !== null) return "deno"; 9 | return "node"; 10 | } 11 | -------------------------------------------------------------------------------- /alchemy/templates/vite/src/worker.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | fetch(request) { 3 | const url = new URL(request.url); 4 | 5 | if (url.pathname.startsWith("/api/")) { 6 | return Response.json({ 7 | name: "Cloudflare", 8 | }); 9 | } 10 | return new Response(null, { status: 404 }); 11 | }, 12 | } satisfies ExportedHandler; 13 | -------------------------------------------------------------------------------- /alchemy/tsconfig.test.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "src/**/*.ts", 5 | "src/**/*.tsx", 6 | "test/**/*.ts", 7 | "./package.json", 8 | "src/runtime/shims.js" 9 | ], 10 | "compilerOptions": { 11 | "rootDir": ".", 12 | "noEmit": true, 13 | "types": ["@cloudflare/workers-types"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/cloudflare-nuxt-pipeline/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | wrangler.jsonc 26 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/app/env.ts: -------------------------------------------------------------------------------- 1 | import type { website } from "../alchemy.run.ts"; 2 | 3 | export type CloudFlareEnv = typeof website.Env; 4 | 5 | declare global { 6 | export type Env = CloudFlareEnv; 7 | } 8 | 9 | declare module "cloudflare:workers" { 10 | namespace Cloudflare { 11 | export interface Env extends CloudFlareEnv {} 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/cloudflare-worker/src/rpc.ts: -------------------------------------------------------------------------------- 1 | import { WorkerEntrypoint } from "cloudflare:workers"; 2 | 3 | export default class MyRPC extends WorkerEntrypoint { 4 | /** 5 | * Hello world 6 | */ 7 | async hello(name: string) { 8 | return `Hello, ${name}!`; 9 | } 10 | async fetch() { 11 | return new Response("Hello from Worker B"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /alchemy-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "include": ["src/**/*", "alchemy.run.ts", ".astro/*.d.ts"], 4 | "compilerOptions": { 5 | "types": ["@cloudflare/workers-types", "astro/client", "./src/env.d.ts"], 6 | "noEmit": true 7 | }, 8 | "references": [ 9 | { 10 | "path": "../alchemy" 11 | } 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; 2 | import alchemy from "alchemy/cloudflare/sveltekit"; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | preprocess: vitePreprocess(), 7 | kit: { 8 | adapter: alchemy(), 9 | }, 10 | }; 11 | 12 | export default config; 13 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/workers/env.ts: -------------------------------------------------------------------------------- 1 | import type { website } from "../alchemy.run.ts"; 2 | 3 | export type CloudflareEnv = typeof website.Env; 4 | 5 | declare global { 6 | type Env = CloudflareEnv; 7 | } 8 | 9 | declare module "cloudflare:workers" { 10 | namespace Cloudflare { 11 | export interface Env extends CloudflareEnv {} 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /alchemy/templates/hono/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "skipLibCheck": true, 8 | "lib": ["ESNext"], 9 | "jsx": "react-jsx", 10 | "jsxImportSource": "hono/jsx", 11 | "types": ["@cloudflare/workers-types"] 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/.gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/nuxt/_gitignore: -------------------------------------------------------------------------------- 1 | # Nuxt dev/build outputs 2 | .output 3 | .data 4 | .nuxt 5 | .nitro 6 | .cache 7 | dist 8 | 9 | # Node dependencies 10 | node_modules 11 | 12 | # Logs 13 | logs 14 | *.log 15 | 16 | # Misc 17 | .DS_Store 18 | .fleet 19 | .idea 20 | 21 | # Local env files 22 | .env 23 | .env.* 24 | !.env.example 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/src/app/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import { RequestInfo } from "rwsdk/worker"; 2 | 3 | export function Home({ ctx }: RequestInfo) { 4 | return ( 5 |
6 |

7 | {ctx.user?.username 8 | ? `You are logged in as user ${ctx.user.username}` 9 | : "You are not logged in"} 10 |

11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": ["vite.config.ts"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "strict": true, 7 | "types": ["node"], 8 | "lib": ["ES2022"], 9 | "target": "ES2022", 10 | "module": "ES2022", 11 | "moduleResolution": "bundler" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /alchemy-web/src/pages/auth/error.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import AuthLayout from '../../components/AuthLayout.astro'; 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Nextjs } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | export const worker = await Nextjs("website", { 7 | name: `${app.name}-${app.stage}-website`, 8 | }); 9 | 10 | console.log({ 11 | url: worker.url, 12 | }); 13 | 14 | await app.finalize(); 15 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.node.json" }, 5 | { "path": "./tsconfig.cloudflare.json" } 6 | ], 7 | "compilerOptions": { 8 | "checkJs": true, 9 | "verbatimModuleSyntax": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "noEmit": true, 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://svelte.dev/docs/kit/types#app.d.ts 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface PageState {} 9 | // interface Platform {} 10 | } 11 | } 12 | 13 | export {}; 14 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/app/routes/_index.tsx: -------------------------------------------------------------------------------- 1 | import { Route } from ".types/routes/_index"; 2 | 3 | export default function Home({}: Route.ComponentProps) { 4 | return ( 5 |
6 |

Hello World 🍊

7 |
8 | ); 9 | } 10 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/livestore/schema.ts: -------------------------------------------------------------------------------- 1 | import { makeSchema, State } from "@livestore/livestore"; 2 | import { events } from "./events.ts"; 3 | import { materializers } from "./materializers.ts"; 4 | import { tables } from "./tables.ts"; 5 | 6 | export const schema = makeSchema({ 7 | events, 8 | state: State.SQLite.makeState({ tables, materializers }), 9 | }); 10 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/next.config.ts: -------------------------------------------------------------------------------- 1 | import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare"; 2 | import type { NextConfig } from "next"; 3 | 4 | const nextConfig: NextConfig = { 5 | /* config options here */ 6 | typescript: { 7 | ignoreBuildErrors: true, 8 | }, 9 | }; 10 | 11 | export default nextConfig; 12 | 13 | initOpenNextCloudflareForDev(); 14 | -------------------------------------------------------------------------------- /scripts/shell.ts: -------------------------------------------------------------------------------- 1 | import { exec } from "../alchemy/src/os/exec.js"; 2 | import { website } from "../stacks/src/website.run.ts"; 3 | 4 | const command = process.argv.slice(2).join(" "); 5 | 6 | if (!command) { 7 | console.error("No command provided"); 8 | process.exit(1); 9 | } 10 | 11 | await exec(command, { 12 | env: { 13 | WEBSITE_URL: website.url, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /alchemy/drizzle/durable-object/0000_far_moon_knight.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `resources` ( 2 | `id` text NOT NULL, 3 | `scope` text NOT NULL, 4 | `status` text NOT NULL, 5 | `kind` text NOT NULL, 6 | `fqn` text NOT NULL, 7 | `seq` integer NOT NULL, 8 | `data` text NOT NULL, 9 | `props` text, 10 | `oldProps` text, 11 | `output` text NOT NULL, 12 | PRIMARY KEY(`scope`, `id`) 13 | ); 14 | -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/src/frontend.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import App from "./App.tsx"; 4 | import "./index.css"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | 12 | if (import.meta.hot) { 13 | import.meta.hot.accept(); 14 | } 15 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "./.nuxt/tsconfig.json", 4 | "compilerOptions": { 5 | "types": [ 6 | "@cloudflare/workers-types", 7 | "./types/env.d.ts" 8 | ] 9 | }, 10 | "include": [ 11 | "alchemy.run.ts", 12 | "types/**/*.ts", 13 | "server/**/*.ts" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /alchemy-web/src/components/ThemeSelect.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import BlogThemeSelect from 'starlight-blog/components/ThemeSelect.astro'; 3 | import NovaThemeSelect from 'starlight-theme-nova/components/ThemeSelect.astro'; 4 | 5 | const props = Astro.props; 6 | --- 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /alchemy-web/src/pages/cloudflare/auth/logout.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import AuthLayout from '../../../components/AuthLayout.astro'; 3 | --- 4 | 5 | 14 | -------------------------------------------------------------------------------- /alchemy/src/type.ts: -------------------------------------------------------------------------------- 1 | export type type = typeof type; 2 | /** 3 | * Used to construct type-level alias information. 4 | */ 5 | export const type = ((): any => { 6 | throw new Error("Should never be called, purely for type-level aliasing"); 7 | }) as (() => T) & 8 | // we also want to make this a "class type" so that syntax highlighting is always as a type 9 | (new () => T); 10 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Output 4 | .output 5 | .vercel 6 | .netlify 7 | .wrangler 8 | /.svelte-kit 9 | /build 10 | 11 | # OS 12 | .DS_Store 13 | Thumbs.db 14 | 15 | # Env 16 | .env 17 | .env.* 18 | !.env.example 19 | !.env.test 20 | 21 | # Vite 22 | vite.config.js.timestamp-* 23 | vite.config.ts.timestamp-* 24 | 25 | .alchemy/ 26 | .env 27 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/_gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Output 4 | .output 5 | .vercel 6 | .netlify 7 | .wrangler 8 | /.svelte-kit 9 | /build 10 | 11 | # OS 12 | .DS_Store 13 | Thumbs.db 14 | 15 | # Env 16 | .env 17 | .env.* 18 | !.env.example 19 | !.env.test 20 | 21 | # Vite 22 | vite.config.js.timestamp-* 23 | vite.config.ts.timestamp-* 24 | 25 | .alchemy/ 26 | .env 27 | .wrangler/ -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/src/frontend.tsx: -------------------------------------------------------------------------------- 1 | import { StrictMode } from "react"; 2 | import { createRoot } from "react-dom/client"; 3 | import App from "./App.tsx"; 4 | import "./index.css"; 5 | 6 | createRoot(document.getElementById("root")!).render( 7 | 8 | 9 | , 10 | ); 11 | 12 | if (import.meta.hot) { 13 | import.meta.hot.accept(); 14 | } 15 | -------------------------------------------------------------------------------- /scripts/generate-pnpm-workspace.yaml.ts: -------------------------------------------------------------------------------- 1 | import { readFile, writeFile } from "node:fs/promises"; 2 | import yaml from "yaml"; 3 | 4 | const pkg = JSON.parse(await readFile("package.json", "utf8")); 5 | const yamlContent = yaml.stringify({ 6 | packages: pkg.workspaces.packages, 7 | catalog: pkg.workspaces.catalog, 8 | }); 9 | await writeFile("pnpm-workspace.yaml", yamlContent, "utf8"); 10 | -------------------------------------------------------------------------------- /alchemy/templates/astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "include": [ 4 | "alchemy.run.ts", 5 | "types/**/*.ts", 6 | ".astro/types.d.ts", 7 | "**/*" 8 | ], 9 | "exclude": [ 10 | "dist" 11 | ], 12 | "compilerOptions": { 13 | "types": [ 14 | "@cloudflare/workers-types", 15 | "./types/env.d.ts" 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /alchemy/src/util/diff.ts: -------------------------------------------------------------------------------- 1 | import { isDeepStrictEqual } from "node:util"; 2 | 3 | /** 4 | * Returns an array of keys in `b` that are different from `a`. 5 | */ 6 | export const diff = (a: T, b: NoInfer) => { 7 | const keys: (keyof T)[] = []; 8 | for (const key in a) { 9 | if (!isDeepStrictEqual(a[key], b[key])) { 10 | keys.push(key); 11 | } 12 | } 13 | return keys; 14 | }; 15 | -------------------------------------------------------------------------------- /examples/cloudflare-nuxt-pipeline/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // https://nuxt.com/docs/guide/concepts/typescript 3 | "extends": "../../tsconfig.base.json", 4 | "compilerOptions": { 5 | "types": ["@cloudflare/workers-types", "./env.d.ts"], 6 | "jsx": "react-jsx", 7 | "noEmit": true 8 | }, 9 | "references": [ 10 | { 11 | "path": "../../alchemy/tsconfig.json" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "types": ["@cloudflare/workers-types"], 5 | "allowImportingTsExtensions": true, 6 | "jsx": "react-jsx", 7 | "noEmit": true 8 | }, 9 | "include": ["bun-env.d.ts", "src/**/*.ts", "src/**/*.tsx"], 10 | "references": [{ "path": "../../alchemy/tsconfig.json" }], 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig.json", 3 | "include": [ 4 | "alchemy.run.ts", 5 | "types/**/*.ts", 6 | "vite.config.ts" 7 | ], 8 | "compilerOptions": { 9 | "composite": true, 10 | "strict": true, 11 | "lib": ["ES2022"], 12 | "target": "ES2022", 13 | "module": "ES2022", 14 | "moduleResolution": "bundler" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/src/router.tsx: -------------------------------------------------------------------------------- 1 | import { createRouter } from "@tanstack/react-router"; 2 | 3 | // Import the generated route tree 4 | import { routeTree } from "./routeTree.gen"; 5 | 6 | // Create a new router instance 7 | export const getRouter = () => { 8 | return createRouter({ 9 | routeTree, 10 | scrollRestoration: true, 11 | defaultPreloadStaleTime: 0, 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /alchemy/bin/services/get-package-version.ts: -------------------------------------------------------------------------------- 1 | import { readJSON } from "fs-extra"; 2 | import path from "pathe"; 3 | import { PKG_ROOT } from "../constants.ts"; 4 | 5 | export const getPackageVersion = async () => { 6 | const packageJsonPath = path.join(PKG_ROOT, "package.json"); 7 | 8 | const packageJsonContent = await readJSON(packageJsonPath); 9 | 10 | return packageJsonContent.version ?? "1.0.0"; 11 | }; 12 | -------------------------------------------------------------------------------- /alchemy/templates/nuxt/nuxt.config.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy/cloudflare/nuxt"; 2 | import { defineNuxtConfig } from "nuxt/config"; 3 | 4 | // https://nuxt.com/docs/api/configuration/nuxt-config 5 | export default defineNuxtConfig({ 6 | devtools: { enabled: true }, 7 | nitro: { 8 | preset: "cloudflare_module", 9 | cloudflare: alchemy(), 10 | }, 11 | modules: ["nitro-cloudflare-dev"], 12 | }); 13 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/app/app.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss" source("."); 2 | 3 | @theme { 4 | --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, 5 | "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 6 | } 7 | 8 | html, 9 | body { 10 | @apply bg-white dark:bg-gray-950; 11 | 12 | @media (prefers-color-scheme: dark) { 13 | color-scheme: dark; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/app/app.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss" source("."); 2 | 3 | @theme { 4 | --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, 5 | "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; 6 | } 7 | 8 | html, 9 | body { 10 | @apply bg-white dark:bg-gray-950; 11 | 12 | @media (prefers-color-scheme: dark) { 13 | color-scheme: dark; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/types/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { website } from "../alchemy.run.ts"; 4 | 5 | export type CloudFlareEnv = typeof website.Env; 6 | 7 | declare global { 8 | export type Env = CloudFlareEnv; 9 | } 10 | 11 | declare module "cloudflare:workers" { 12 | namespace Cloudflare { 13 | export interface Env extends CloudFlareEnv {} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/src/router.tsx: -------------------------------------------------------------------------------- 1 | import { createRouter } from "@tanstack/react-router"; 2 | 3 | // Import the generated route tree 4 | import { routeTree } from "./routeTree.gen.ts"; 5 | 6 | // Create a new router instance 7 | export const getRouter = () => { 8 | return createRouter({ 9 | routeTree, 10 | scrollRestoration: true, 11 | defaultPreloadStaleTime: 0, 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /examples/cloudflare-vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "types": ["@cloudflare/workers-types"], 5 | "allowImportingTsExtensions": true, 6 | "jsx": "react-jsx", 7 | "noEmit": true 8 | }, 9 | "include": ["vite/*.ts", "src/**/*.ts", "src/**/*.tsx", "src/env.d.ts"], 10 | "references": [{ "path": "../../alchemy/tsconfig.json" }] 11 | } 12 | -------------------------------------------------------------------------------- /alchemy-web/src/pages/auth/success.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import AuthLayout from '../../components/AuthLayout.astro'; 3 | --- 4 | 5 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/browser-rendering.ts: -------------------------------------------------------------------------------- 1 | export type BrowserRendering = { 2 | type: "browser"; 3 | }; 4 | 5 | /** 6 | * Creates a browser rendering binding for running browser tasks in Workers. 7 | * 8 | * @example 9 | * ```ts 10 | * const browser = BrowserRendering(); 11 | * ``` 12 | */ 13 | export function BrowserRendering(): BrowserRendering { 14 | return { 15 | type: "browser", 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/src/app/pages/Home.tsx: -------------------------------------------------------------------------------- 1 | import type { RequestInfo } from "rwsdk/worker"; 2 | import { users } from "../../db/schema.js"; 3 | 4 | export async function Home({ ctx }: RequestInfo) { 5 | const allUsers = await ctx.db.select().from(users).all(); 6 | return ( 7 |
8 |

Hello World

9 |
{JSON.stringify(allUsers, null, 2)}
10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /alchemy-web/src/pages/cloudflare/auth/callback.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import AuthLayout from '../../../components/AuthLayout.astro'; 3 | --- 4 | 5 | 14 | -------------------------------------------------------------------------------- /alchemy/templates/typescript/README.md: -------------------------------------------------------------------------------- 1 | # my-alchemy-app 2 | 3 | [![Deployed with Alchemy](https://alchemy.run/alchemy-badge.svg)](https://alchemy.run) 4 | 5 | To install dependencies: 6 | 7 | ```bash 8 | bun install 9 | ``` 10 | 11 | To run: 12 | 13 | ```bash 14 | bun run index.ts 15 | ``` 16 | 17 | This project was created using `bun init` in bun v1.2.16. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 18 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/livestore/worker.ts: -------------------------------------------------------------------------------- 1 | import { makeWorker } from "@livestore/adapter-web/worker"; 2 | import { makeCfSync } from "@livestore/sync-cf"; 3 | 4 | import { schema } from "./schema.ts"; 5 | 6 | makeWorker({ 7 | schema, 8 | sync: { 9 | backend: makeCfSync({ url: import.meta.env.VITE_LIVESTORE_SYNC_URL! }), 10 | initialSyncOptions: { _tag: "Blocking", timeout: 5000 }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.base.json", 3 | "compilerOptions": { 4 | "types": ["@cloudflare/workers-types"], 5 | "allowImportingTsExtensions": true, 6 | "jsx": "react-jsx", 7 | "noEmit": true 8 | }, 9 | "include": ["vite/*.ts", "src/**/*.ts", "src/**/*.tsx", "src/env.d.ts"], 10 | "references": [{ "path": "../../alchemy/tsconfig.json" }] 11 | } 12 | -------------------------------------------------------------------------------- /examples/planetscale-postgres/src/schema.ts: -------------------------------------------------------------------------------- 1 | import { pgTable, timestamp, uuid, varchar } from "drizzle-orm/pg-core"; 2 | 3 | export const users = pgTable("users", { 4 | id: uuid().primaryKey().defaultRandom(), 5 | email: varchar({ length: 255 }).notNull(), 6 | password: varchar({ length: 255 }).notNull(), 7 | createdAt: timestamp().notNull().defaultNow(), 8 | updatedAt: timestamp().notNull().defaultNow(), 9 | }); 10 | -------------------------------------------------------------------------------- /alchemy/src/aws/ec2/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./internet-gateway-attachment.ts"; 2 | export * from "./internet-gateway.ts"; 3 | export * from "./nat-gateway.ts"; 4 | export * from "./route-table-association.ts"; 5 | export * from "./route-table.ts"; 6 | export * from "./route.ts"; 7 | export * from "./security-group-rule.ts"; 8 | export * from "./security-group.ts"; 9 | export * from "./subnet.ts"; 10 | export * from "./vpc.ts"; 11 | -------------------------------------------------------------------------------- /alchemy/templates/sveltekit/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /alchemy/templates/vite/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/vite/_gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/nextjs/types/env.d.ts: -------------------------------------------------------------------------------- 1 | // Auto-generated Cloudflare binding types. 2 | // @see https://alchemy.run/concepts/bindings/#type-safe-bindings 3 | 4 | import type { website } from "./alchemy.run.ts"; 5 | 6 | declare global { 7 | type CloudflareEnv = typeof website.Env; 8 | } 9 | 10 | declare module "cloudflare:workers" { 11 | namespace Cloudflare { 12 | export interface Env extends CloudflareEnv {} 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/test-handlers/async-hooks-handler.ts: -------------------------------------------------------------------------------- 1 | // Test handler that imports node:async_hooks to trigger specific warnings 2 | import { AsyncLocalStorage } from "node:async_hooks"; 3 | 4 | export default { 5 | async fetch(): Promise { 6 | const als = new AsyncLocalStorage(); 7 | return new Response( 8 | `AsyncLocalStorage available: ${typeof als.run === "function"}`, 9 | ); 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import type { website } from "../alchemy.run.ts"; 4 | 5 | export type CloudflareEnv = typeof website.Env; 6 | 7 | declare global { 8 | export type Env = CloudflareEnv; 9 | } 10 | 11 | declare module "cloudflare:workers" { 12 | namespace Cloudflare { 13 | export interface Env extends CloudflareEnv {} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-loader/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-worker-loader", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "tsc -b", 7 | "deploy": "alchemy deploy --env-file ../../.env", 8 | "destroy": "alchemy destroy --env-file ../../.env", 9 | "dev": "alchemy dev --env-file ../../.env" 10 | }, 11 | "dependencies": { 12 | "alchemy": "workspace:*" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /examples/planetscale-drizzle/database/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "drizzle-kit"; 2 | 3 | export default defineConfig({ 4 | out: "./drizzle", 5 | schema: "./src/schema.ts", 6 | dialect: "mysql", 7 | dbCredentials: { 8 | url: `mysql://${process.env.DATABASE_USERNAME}:${process.env.DATABASE_PASSWORD}@${process.env.DATABASE_HOST}/${process.env.DATABASE_NAME}?ssl={"rejectUnauthorized":true}`, 9 | }, 10 | }); 11 | -------------------------------------------------------------------------------- /tests/smoke-test-flatten-website/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/astro/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # jetbrains setting folder 24 | .idea/ 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/astro/_gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | 4 | # generated types 5 | .astro/ 6 | 7 | # dependencies 8 | node_modules/ 9 | 10 | # logs 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # jetbrains setting folder 24 | .idea/ 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/_gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | 26 | .alchemy/ 27 | .env 28 | .wrangler/ 29 | 30 | -------------------------------------------------------------------------------- /alchemy/templates/rwsdk/src/session/store.ts: -------------------------------------------------------------------------------- 1 | import { defineDurableSession } from "rwsdk/auth"; 2 | 3 | export let sessions: ReturnType; 4 | 5 | const createSessionStore = (env: Env) => 6 | defineDurableSession({ 7 | sessionDurableObject: env.SESSION_DURABLE_OBJECT, 8 | }); 9 | 10 | export const setupSessionStore = (env: Env) => { 11 | sessions = createSessionStore(env); 12 | return sessions; 13 | }; 14 | -------------------------------------------------------------------------------- /example-monorepo/apps/frontend/src/worker.ts: -------------------------------------------------------------------------------- 1 | import type { frontend } from "../alchemy.run.ts"; 2 | 3 | export default { 4 | fetch(request) { 5 | const url = new URL(request.url); 6 | 7 | if (url.pathname.startsWith("/api/")) { 8 | return Response.json({ 9 | name: "Cloudflare", 10 | }); 11 | } 12 | return new Response(null, { status: 404 }); 13 | }, 14 | } satisfies ExportedHandler; 15 | -------------------------------------------------------------------------------- /examples/cloudflare-astro/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Astro } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("cloudflare-astro"); 5 | 6 | export const website = await Astro("website", { 7 | name: `${app.name}-${app.stage}-website`, 8 | dev: { 9 | command: "astro dev --port 5000", 10 | }, 11 | }); 12 | 13 | console.log({ 14 | url: website.url, 15 | }); 16 | 17 | await app.finalize(); 18 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Orange } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("cloudflare-orange"); 5 | 6 | export const website = await Orange("website", { 7 | name: `${app.name}-${app.stage}-website`, 8 | dev: { 9 | command: "vite dev --port 5003", 10 | }, 11 | }); 12 | 13 | console.log({ 14 | url: website.url, 15 | }); 16 | 17 | await app.finalize(); 18 | -------------------------------------------------------------------------------- /examples/cloudflare-orange/vite.config.ts: -------------------------------------------------------------------------------- 1 | import orange from "@orange-js/vite"; 2 | import tailwindcss from "@tailwindcss/vite"; 3 | import { defineConfig } from "vite"; 4 | import tsconfigPaths from "vite-tsconfig-paths"; 5 | 6 | export default defineConfig({ 7 | plugins: [ 8 | orange(), 9 | tsconfigPaths({ 10 | root: ".", 11 | }), 12 | tailwindcss(), 13 | ], 14 | build: { 15 | minify: true, 16 | }, 17 | }); 18 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": [], 3 | "references": [ 4 | { "path": "./tsconfig.node.json" }, 5 | { "path": "./tsconfig.cloudflare.json" }, 6 | ], 7 | "compilerOptions": { 8 | "checkJs": true, 9 | "verbatimModuleSyntax": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "noEmit": true, 13 | "types": ["./workers/env.ts", "@cloudflare/workers-types"] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { R2Bucket, TanStackStart } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | const r2 = await R2Bucket("r2"); 7 | 8 | export const website = await TanStackStart("website", { 9 | bindings: { 10 | R2: r2, 11 | }, 12 | }); 13 | 14 | console.log({ 15 | url: website.url, 16 | }); 17 | 18 | await app.finalize(); 19 | -------------------------------------------------------------------------------- /alchemy/templates/vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /example-monorepo/apps/backend/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { backend } from "../alchemy.run.ts"; 2 | 3 | export default { 4 | fetch: async (req, env) => { 5 | const bearer = req.headers.get("Authorization"); 6 | if (bearer !== `Bearer ${env.API_KEY}`) { 7 | return new Response("Unauthorized", { status: 401 }); 8 | } 9 | return new Response("Welcome, you are authorized!"); 10 | }, 11 | } as ExportedHandler; 12 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Output 4 | .output 5 | .vercel 6 | .netlify 7 | .wrangler 8 | /.svelte-kit 9 | /build 10 | 11 | # OS 12 | .DS_Store 13 | Thumbs.db 14 | 15 | # Env 16 | .env 17 | .env.* 18 | !.env.example 19 | !.env.test 20 | 21 | # Vite 22 | vite.config.js.timestamp-* 23 | vite.config.ts.timestamp-* 24 | 25 | # committed so that our smoke tests can run `build` as part of checking 26 | !wrangler.jsonc -------------------------------------------------------------------------------- /examples/cloudflare-vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-loader/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Worker, WorkerLoader } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("cloudflare-worker-loader"); 5 | 6 | export const worker = await Worker("worker", { 7 | entrypoint: "./src/worker.ts", 8 | bindings: { 9 | LOADER: WorkerLoader(), 10 | }, 11 | }); 12 | 13 | console.log(`Worker URL: ${worker.url}`); 14 | 15 | await app.finalize(); 16 | -------------------------------------------------------------------------------- /alchemy/src/util/ignore.ts: -------------------------------------------------------------------------------- 1 | export async function ignore( 2 | codes: string | string[], 3 | fn: () => Promise, 4 | ): Promise { 5 | try { 6 | return await fn(); 7 | } catch (error: any) { 8 | const errorCode = error.code || error.name; 9 | if ( 10 | Array.isArray(codes) ? codes.includes(errorCode) : errorCode === codes 11 | ) { 12 | return undefined; 13 | } 14 | throw error; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /example-monorepo/apps/analytics/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { analytics } from "../alchemy.run.js"; 2 | 3 | export default { 4 | fetch: async (req, env) => { 5 | const bearer = req.headers.get("Authorization"); 6 | if (bearer !== `Bearer ${env.API_KEY}`) { 7 | return new Response("Unauthorized", { status: 401 }); 8 | } 9 | return new Response("Welcome, you are authorized!"); 10 | }, 11 | } as ExportedHandler; 12 | -------------------------------------------------------------------------------- /example-monorepo/apps/frontend/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/main.tsx: -------------------------------------------------------------------------------- 1 | import "todomvc-app-css/index.css"; 2 | 3 | import React from "react"; 4 | import ReactDOM from "react-dom/client"; 5 | 6 | import { App } from "./Root.js"; 7 | 8 | ReactDOM.createRoot(document.getElementById("react-app")!).render(); 9 | 10 | // ReactDOM.createRoot(document.getElementById('react-app')!).render( 11 | // 12 | // 13 | // , 14 | // ) 15 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/smoke-test-flatten-website/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | lib/ 4 | .out/ 5 | .test/ 6 | .DS_Store 7 | .env 8 | *.tsbuildinfo 9 | 10 | .alchemy/ 11 | # !.alchemy/github:alchemy/ 12 | # examples/*/.alchemy 13 | 14 | .repomix-output.txt 15 | wrangler.jsonc 16 | 17 | # Husky - ignore generated files but keep hooks 18 | .husky/_ 19 | !.husky/pre-commit 20 | 21 | .smoke 22 | .smoke.logs 23 | smoke 24 | .svelte-kit 25 | .claude/*.local.json 26 | .astro 27 | .wrangler 28 | 29 | *.tgz 30 | -------------------------------------------------------------------------------- /alchemy-web/src/content.config.ts: -------------------------------------------------------------------------------- 1 | import { docsLoader } from "@astrojs/starlight/loaders"; 2 | import { docsSchema } from "@astrojs/starlight/schema"; 3 | import { defineCollection } from "astro:content"; 4 | import { blogSchema } from "starlight-blog/schema"; 5 | 6 | export const collections = { 7 | docs: defineCollection({ 8 | loader: docsLoader(), 9 | schema: docsSchema({ 10 | extend: (ctx) => blogSchema(ctx), 11 | }), 12 | }), 13 | }; 14 | -------------------------------------------------------------------------------- /alchemy/drizzle/default/meta/_journal.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "7", 3 | "dialect": "sqlite", 4 | "entries": [ 5 | { 6 | "idx": 0, 7 | "version": "6", 8 | "when": 1751858205551, 9 | "tag": "0000_busy_mauler", 10 | "breakpoints": true 11 | }, 12 | { 13 | "idx": 1, 14 | "version": "6", 15 | "when": 1751942782611, 16 | "tag": "0001_concerned_iceman", 17 | "breakpoints": true 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /alchemy/src/cloudflare/bundle/plugin-als-external.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin } from "esbuild"; 2 | 3 | /** 4 | * An esbuild plugin that will mark `node:async_hooks` imports as external. 5 | */ 6 | export const esbuildPluginAsyncLocalStorage: Plugin = { 7 | name: "async-local-storage-imports", 8 | setup(pluginBuild) { 9 | pluginBuild.onResolve({ filter: /^node:async_hooks(\/|$)/ }, () => { 10 | return { external: true }; 11 | }); 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /alchemy/templates/hono/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from "hono"; 2 | 3 | const app = new Hono<{ Bindings: Env }>(); 4 | 5 | app.get("/", (c) => { 6 | return c.text("Hello Hono!"); 7 | }); 8 | 9 | app.get("/kv", async (c) => { 10 | const key = "hello"; 11 | const value = `world@${Date.now()}`; 12 | await c.env.KV.put(key, value); 13 | const got = await c.env.KV.get(key); 14 | return c.json({ key, value: got }); 15 | }); 16 | 17 | export default app; 18 | -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Bun + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /alchemy/templates/astro/src/pages/index.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import Welcome from '../components/Welcome.astro'; 3 | import Layout from '../layouts/Layout.astro'; 4 | 5 | // Welcome to Astro! Wondering what to do next? Check out the Astro documentation at https://docs.astro.build 6 | // Don't want to use any of this? Delete everything in this file, the `assets`, `components`, and `layouts` directories, and start fresh. 7 | --- 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Bun + React + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /alchemy/templates/hono/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { KVNamespace, Worker } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("{projectName}"); 5 | 6 | const kv = await KVNamespace("kv", { 7 | title: "kv", 8 | }); 9 | 10 | export const worker = await Worker("worker", { 11 | entrypoint: "src/index.ts", 12 | bindings: { 13 | KV: kv, 14 | }, 15 | }); 16 | 17 | console.log(worker.url); 18 | 19 | await app.finalize(); 20 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import "dotenv/config"; 2 | import { defineConfig } from "drizzle-kit"; 3 | 4 | export default defineConfig({ 5 | out: "./drizzle", 6 | schema: "./src/db/schema.ts", 7 | dialect: "sqlite", 8 | driver: "d1-http", 9 | dbCredentials: { 10 | accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, 11 | databaseId: process.env.CLOUDFLARE_DATABASE_ID!, 12 | token: process.env.CLOUDFLARE_D1_TOKEN!, 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/src/app.d.ts: -------------------------------------------------------------------------------- 1 | import type { CloudflarePlatform } from "./env.ts"; 2 | 3 | // See https://svelte.dev/docs/kit/types#app.d.ts 4 | // for information about these interfaces 5 | declare global { 6 | namespace App { 7 | // interface Error {} 8 | // interface Locals {} 9 | // interface PageData {} 10 | // interface PageState {} 11 | interface Platform extends CloudflarePlatform {} 12 | } 13 | } 14 | 15 | // export { }; 16 | -------------------------------------------------------------------------------- /alchemy/src/index.ts: -------------------------------------------------------------------------------- 1 | export type { AlchemyOptions, Phase } from "./alchemy.ts"; 2 | export type * from "./context.ts"; 3 | 4 | export * from "./resource.ts"; 5 | export * from "./scope.ts"; 6 | export * from "./secret.ts"; 7 | export * from "./serde.ts"; 8 | export * from "./state.ts"; 9 | export * from "./type.ts"; 10 | export * from "./util/ignore.ts"; 11 | export * from "./util/logger.ts"; 12 | 13 | import { alchemy } from "./alchemy.ts"; 14 | export default alchemy; 15 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import "./globals.css"; 3 | 4 | export const metadata: Metadata = { 5 | title: "Next.js on Cloudflare Workers", 6 | description: "Built with Alchemy", 7 | }; 8 | 9 | export default function RootLayout({ 10 | children, 11 | }: { 12 | children: React.ReactNode; 13 | }) { 14 | return ( 15 | 16 | {children} 17 | 18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/util/store-id.ts: -------------------------------------------------------------------------------- 1 | export const getStoreId = () => { 2 | if (typeof window === "undefined") return "unused"; 3 | 4 | const searchParams = new URLSearchParams(window.location.search); 5 | const storeId = searchParams.get("storeId"); 6 | if (storeId !== null) return storeId; 7 | 8 | const newAppId = crypto.randomUUID(); 9 | searchParams.set("storeId", newAppId); 10 | 11 | window.location.search = searchParams.toString(); 12 | }; 13 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/open-next.config.ts: -------------------------------------------------------------------------------- 1 | import { defineCloudflareConfig } from "@opennextjs/cloudflare"; 2 | 3 | export default defineCloudflareConfig({ 4 | // Uncomment to enable R2 cache, 5 | // It should be imported as: 6 | // `import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";` 7 | // See https://opennext.js.org/cloudflare/caching for more details 8 | // incrementalCache: r2IncrementalCache, 9 | }); 10 | -------------------------------------------------------------------------------- /alchemy/bin/errors.ts: -------------------------------------------------------------------------------- 1 | import { log } from "@clack/prompts"; 2 | import pc from "picocolors"; 3 | 4 | export function throwWithContext(error: unknown, context: string): never { 5 | const errorMsg = error instanceof Error ? error.message : String(error); 6 | log.error(pc.red(`❌ ${context}`)); 7 | log.error(pc.gray(` ${errorMsg}`)); 8 | throw new Error(`${context}: ${errorMsg}`, { 9 | cause: error instanceof Error ? error : new Error(String(error)), 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/src/routes/api.demo-names.ts: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from "@tanstack/react-router"; 2 | 3 | export const Route = createFileRoute("/api/demo-names")({ 4 | server: { 5 | handlers: { 6 | GET: () => { 7 | return new Response(JSON.stringify(["Alice", "Bob", "Charlie"]), { 8 | headers: { 9 | "Content-Type": "application/json", 10 | }, 11 | }); 12 | }, 13 | }, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/src/routes/api.demo-names.ts: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from "@tanstack/react-router"; 2 | 3 | export const Route = createFileRoute("/api/demo-names")({ 4 | server: { 5 | handlers: { 6 | GET: () => { 7 | return new Response(JSON.stringify(["Alice", "Bob", "Charlie"]), { 8 | headers: { 9 | "Content-Type": "application/json", 10 | }, 11 | }); 12 | }, 13 | }, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/src/routes/api.test.env.ts: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from "@tanstack/react-router"; 2 | import { json } from "@tanstack/react-start"; 3 | import { env } from "cloudflare:workers"; 4 | 5 | export const Route = createFileRoute("/api/test/env")({ 6 | server: { 7 | handlers: { 8 | GET: () => { 9 | return json({ 10 | TEST_SECRET_VALUE: env.TEST_SECRET_VALUE, 11 | }); 12 | }, 13 | }, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /alchemy-web/src/content/docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Infrastructure as TypeScript 3 | template: splash 4 | editUrl: false 5 | hero: 6 | tagline: Deploy to Cloudflare, AWS, and more with pure TypeScript. Generate support for any API in minutes with AI. 7 | actions: 8 | - text: Quick Start 9 | link: /getting-started 10 | variant: primary 11 | - text: ⭐ Star on GitHub 12 | link: https://github.com/alchemy-run/alchemy 13 | variant: secondary 14 | --- 15 | -------------------------------------------------------------------------------- /scripts/test-monorepo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # let's use the repo's alchemy version (but we can't use workspace:* so must use link) 4 | cd alchemy 5 | bun link 6 | # install deps and tsc -b 7 | cd ../example-monorepo 8 | bun i 9 | bun run build 10 | # deploy backend and then frontend 11 | bun run deploy 12 | # destroy frontend and then backend 13 | bun run destroy 14 | # second destroy is to ensure that it still works even if `backend` has already been destroyed 15 | bun run destroy -------------------------------------------------------------------------------- /example-monorepo/apps/frontend/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { Vite } from "alchemy/cloudflare"; 3 | import { analytics } from "analytics/alchemy"; 4 | import { backend } from "backend/alchemy"; 5 | 6 | const app = await alchemy("frontend"); 7 | 8 | export const frontend = await Vite("website", { 9 | bindings: { 10 | backend, 11 | analytics, 12 | }, 13 | }); 14 | 15 | console.log({ 16 | url: frontend.url, 17 | }); 18 | 19 | await app.finalize(); 20 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-simple/src/worker2.ts: -------------------------------------------------------------------------------- 1 | import { WorkerEntrypoint } from "cloudflare:workers"; 2 | import type { worker2 } from "../alchemy.run.ts"; 3 | 4 | export default class Worker2 extends WorkerEntrypoint { 5 | declare env: typeof worker2.Env; 6 | 7 | async fetch(request: Request): Promise { 8 | const stub = this.env.DO.getByName("DO"); 9 | return await stub.fetch(request); 10 | } 11 | rpcMethod() { 12 | return "hello world"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /alchemy/src/util/validate-resource-id.ts: -------------------------------------------------------------------------------- 1 | export function validateResourceID(id: string, qualifier = "Resource"): void { 2 | //todo(sam): during effect rewrite, this should be much more limiting 3 | //todo: its hard to undo the flexibility we've offered to users now 4 | if (!id) { 5 | throw new Error(`${qualifier} ID cannot be an empty string: "${id}"`); 6 | } 7 | if (id.includes(":")) { 8 | throw new Error(`${qualifier} ID cannot include colons: "${id}"`); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /alchemy/templates/hono/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@alchemy.run/hono-template", 3 | "type": "module", 4 | "scripts": { 5 | "check": "tsc --noEmit", 6 | "dev": "alchemy dev", 7 | "deploy": "alchemy deploy", 8 | "destroy": "alchemy destroy" 9 | }, 10 | "dependencies": { 11 | "hono": "^4.9.2" 12 | }, 13 | "devDependencies": { 14 | "@cloudflare/workers-types": "^4.20250820.0", 15 | "@types/node": "^24.3.0", 16 | "alchemy": "workspace:*" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/version-metadata-handler.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | async fetch(_request: Request, env: any): Promise { 3 | if (env.IMAGES && env.IMAGES.type === "images") { 4 | return new Response("Images binding available", { status: 200 }); 5 | } 6 | if (env.VERSION_METADATA) { 7 | return new Response("VersionMetadata binding available", { status: 200 }); 8 | } 9 | return new Response("Binding not found", { status: 500 }); 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /example-monorepo/apps/backend/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["alchemy.run.ts", "src/**/*.ts"], 3 | "exclude": ["node_modules", "lib"], 4 | "compilerOptions": { 5 | "rootDir": ".", 6 | "outDir": "./lib", 7 | "composite": true, 8 | "module": "ESNext", 9 | "target": "ESNext", 10 | "moduleResolution": "bundler", 11 | "types": ["@cloudflare/workers-types"], 12 | "declaration": true, 13 | "declarationMap": true, 14 | "skipLibCheck": true 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/src/env.d.ts: -------------------------------------------------------------------------------- 1 | import type { website } from "../alchemy.run.ts"; 2 | 3 | export interface CloudflarePlatform { 4 | env: typeof website.Env; 5 | context: ExecutionContext; 6 | caches: CacheStorage & { default: Cache }; 7 | } 8 | 9 | declare global { 10 | export type CloudflareEnv = typeof website.Env; 11 | } 12 | 13 | declare module "cloudflare:workers" { 14 | namespace Cloudflare { 15 | export interface Env extends CloudflareEnv {} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/bundle/nodejs-builtin-modules.ts: -------------------------------------------------------------------------------- 1 | import { builtinModules } from "node:module"; 2 | 3 | export const NODEJS_MODULES_RE = new RegExp( 4 | `^(node:)?(${builtinModules 5 | .filter( 6 | (m) => 7 | ![ 8 | // in some runtimes (like bun), `ws` is a built-in module but is not in `node` 9 | // bundling for `nodejs_compat` should not polyfill these modules 10 | "ws", 11 | ].includes(m), 12 | ) 13 | .join("|")})$`, 14 | ); 15 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/src/styles.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | body { 4 | @apply m-0; 5 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 6 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 7 | sans-serif; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | } 11 | 12 | code { 13 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 14 | monospace; 15 | } 16 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { ReactRouter } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("cloudflare-react-router"); 5 | 6 | export const website = await ReactRouter("website", { 7 | name: `${app.name}-${app.stage}-website`, 8 | bindings: { 9 | ALCHEMY_TEST_VALUE: alchemy.secret("Hello from Alchemy!"), 10 | }, 11 | }); 12 | 13 | console.log({ 14 | url: website.url, 15 | }); 16 | 17 | await app.finalize(); 18 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/src/styles.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | body { 4 | @apply m-0; 5 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 6 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 7 | sans-serif; 8 | -webkit-font-smoothing: antialiased; 9 | -moz-osx-font-smoothing: grayscale; 10 | } 11 | 12 | code { 13 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 14 | monospace; 15 | } 16 | -------------------------------------------------------------------------------- /alchemy/src/fs/file-ref.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Reference to a file in the filesystem 3 | */ 4 | export type FileRef = { 5 | /** 6 | * Type identifier for FileRef 7 | */ 8 | kind: "fs::FileRef"; 9 | /** 10 | * Path to the file 11 | */ 12 | path: string; 13 | }; 14 | 15 | export function isFileRef(value: unknown): value is FileRef { 16 | return ( 17 | typeof value === "object" && 18 | value !== null && 19 | "kind" in value && 20 | value.kind === "fs::FileRef" 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/fetch-utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Utility functions for making HTTP requests with retry logic for Cloudflare's 3 | * eventually consistent control plane. 4 | */ 5 | 6 | import { expect } from "vitest"; 7 | import { fetchAndExpectOK } from "../../src/util/safe-fetch.ts"; 8 | 9 | export async function fetchAndExpect(url: string, expected: string) { 10 | const response = await fetchAndExpectOK(url); 11 | const text = await response.text(); 12 | expect(text).toEqual(expected); 13 | } 14 | -------------------------------------------------------------------------------- /alchemy/test/docker/fixtures/multi-stage/Dockerfile: -------------------------------------------------------------------------------- 1 | # Stage 1: Build stage 2 | FROM node:16-alpine AS builder 3 | 4 | WORKDIR /app 5 | 6 | # Create a simple index.js file 7 | RUN echo 'console.log("Hello from Alchemy multi-stage build");' > index.js 8 | 9 | # Stage 2: Production stage 10 | FROM node:16-alpine AS production 11 | 12 | WORKDIR /app 13 | 14 | # Copy only what we need from the builder stage 15 | COPY --from=builder /app/index.js . 16 | 17 | # Set the command 18 | CMD ["node", "index.js"] 19 | -------------------------------------------------------------------------------- /examples/cloudflare-vite-container/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | FROM golang:latest AS build 4 | 5 | # Set destination for COPY 6 | WORKDIR /app 7 | 8 | # Download any Go modules 9 | COPY container_src/go.mod ./ 10 | RUN go mod download 11 | 12 | # Copy container source code 13 | COPY container_src/*.go ./ 14 | 15 | # Build 16 | RUN CGO_ENABLED=0 GOOS=linux go build -o /server 17 | 18 | FROM scratch 19 | COPY --from=build /server /server 20 | EXPOSE 8080 21 | 22 | # Run 23 | CMD ["/server"] -------------------------------------------------------------------------------- /alchemy/test/cloudflare/test-helpers.ts: -------------------------------------------------------------------------------- 1 | import { expect } from "vitest"; 2 | import type { CloudflareApi } from "../../src/cloudflare/api.ts"; 3 | 4 | /** 5 | * Helper function to check if a worker exists and assert it doesn't 6 | */ 7 | export async function assertWorkerDoesNotExist( 8 | api: CloudflareApi, 9 | workerName: string, 10 | ) { 11 | const response = await api.get( 12 | `/accounts/${api.accountId}/workers/scripts/${workerName}`, 13 | ); 14 | expect(response.status).toEqual(404); 15 | } 16 | -------------------------------------------------------------------------------- /example-monorepo/apps/analytics/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["alchemy.run.ts", "src/**/*.ts"], 3 | "exclude": ["node_modules", "lib"], 4 | "compilerOptions": { 5 | "rootDir": ".", 6 | "outDir": "./lib", 7 | "composite": true, 8 | "module": "ESNext", 9 | "target": "ESNext", 10 | "moduleResolution": "bundler", 11 | "types": ["@cloudflare/workers-types"], 12 | "declaration": true, 13 | "declarationMap": true, 14 | "skipLibCheck": true 15 | } 16 | } -------------------------------------------------------------------------------- /examples/cloudflare-redwood/src/app/Document.tsx: -------------------------------------------------------------------------------- 1 | export const Document: React.FC<{ children: React.ReactNode }> = ({ 2 | children, 3 | }) => ( 4 | 5 | 6 | 7 | 8 | @redwoodjs/starter-drizzle 9 | 14 | 15 | 16 | ); 17 | -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | import alchemy from "alchemy"; 4 | import { BunSPA } from "alchemy/cloudflare"; 5 | 6 | const app = await alchemy("{projectName}"); 7 | 8 | export const bunsite = await BunSPA("bun-spa-site", { 9 | entrypoint: "src/worker.ts", 10 | frontend: ["src/index.html"], 11 | // Use Cloudflare bindings in your worker as normal 12 | bindings: { 13 | SOME_VALUE: "some-value", 14 | }, 15 | }); 16 | 17 | console.log({ 18 | url: bunsite.url, 19 | }); 20 | 21 | await app.finalize(); 22 | -------------------------------------------------------------------------------- /alchemy/templates/nextjs/src/app/api/hello/route.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest } from "next/server"; 2 | 3 | export async function GET(request: NextRequest) { 4 | return Response.json({ 5 | message: "Hello from Next.js on Cloudflare Workers!", 6 | timestamp: new Date().toISOString(), 7 | url: request.url, 8 | }); 9 | } 10 | 11 | export async function POST(request: NextRequest) { 12 | const body = await request.json(); 13 | 14 | return Response.json({ 15 | message: "POST received", 16 | data: body, 17 | timestamp: new Date().toISOString(), 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /alchemy/templates/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@alchemy.run/typescript-template", 3 | "version": "0.0.0", 4 | "description": "Alchemy Typescript Project", 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc -b", 8 | "deploy": "alchemy deploy", 9 | "destroy": "alchemy destroy", 10 | "dev": "alchemy dev" 11 | }, 12 | "devDependencies": { 13 | "alchemy": "workspace:*", 14 | "@cloudflare/workers-types": "^4.20250805.0", 15 | "miniflare": "^4.20250617.3", 16 | "@types/node": "^24.0.3", 17 | "typescript": "^5.8.3" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { KVNamespace, Nextjs } from "alchemy/cloudflare"; 3 | 4 | const app = await alchemy("cloudflare-nextjs"); 5 | 6 | export const kv = await KVNamespace("kv"); 7 | 8 | export const website = await Nextjs("website", { 9 | adopt: true, 10 | bindings: { KV: kv }, 11 | }); 12 | console.log(`Website: ${website.url}`); 13 | 14 | if (process.env.ALCHEMY_E2E) { 15 | const { test } = await import("./test/e2e.js"); 16 | await test({ 17 | url: website.url, 18 | }); 19 | } 20 | 21 | await app.finalize(); 22 | -------------------------------------------------------------------------------- /.cursor/rules/cloudflare.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: 3 | globs: alchemy/src/cloudflare/* 4 | alwaysApply: false 5 | --- 6 | When adding a new resource that can be bound to a worker, make sure to update: 7 | 8 | 1. bindings.ts - add the binding type to the union 9 | 2. bound.ts - map the Alchemy resource to the Cloudflare runtime binding type 10 | 3. worker.ts - map the binding to the cloduflare metadata api 11 | 4. {resource}.ts - add a new file for the resource alchemy/src/cloudflare/{resource}.ts 12 | 5. {resource}.test.ts - add a new file for the resource alchemy/test/cloudflare/{resource}.test.ts -------------------------------------------------------------------------------- /alchemy/drizzle/default/0000_busy_mauler.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `resources` ( 2 | `id` text NOT NULL, 3 | `scope` text NOT NULL, 4 | `status` text NOT NULL, 5 | `kind` text NOT NULL, 6 | `fqn` text NOT NULL, 7 | `seq` integer NOT NULL, 8 | `data` text NOT NULL, 9 | `props` text, 10 | `oldProps` text, 11 | `output` text NOT NULL, 12 | PRIMARY KEY(`scope`, `id`), 13 | FOREIGN KEY (`scope`) REFERENCES `scopes`(`chain`) ON UPDATE no action ON DELETE no action 14 | ); 15 | --> statement-breakpoint 16 | CREATE TABLE `scopes` ( 17 | `chain` text PRIMARY KEY NOT NULL, 18 | `parent` text 19 | ); 20 | -------------------------------------------------------------------------------- /alchemy/templates/bun-spa/bun-env.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by `bun init` 2 | 3 | declare module "*.svg" { 4 | /** 5 | * A path to the SVG file 6 | */ 7 | const path: `${string}.svg`; 8 | export = path; 9 | } 10 | 11 | declare module "*.png" { 12 | /** 13 | * A path to the PNG file 14 | */ 15 | const path: `${string}.png`; 16 | export = path; 17 | } 18 | 19 | declare module "*.module.css" { 20 | /** 21 | * A record of class names to their corresponding CSS module classes 22 | */ 23 | const classes: { readonly [key: string]: string }; 24 | export = classes; 25 | } 26 | -------------------------------------------------------------------------------- /examples/cloudflare-bun-spa/bun-env.d.ts: -------------------------------------------------------------------------------- 1 | // Generated by `bun init` 2 | 3 | declare module "*.svg" { 4 | /** 5 | * A path to the SVG file 6 | */ 7 | const path: `${string}.svg`; 8 | export = path; 9 | } 10 | 11 | declare module "*.png" { 12 | /** 13 | * A path to the SVG file 14 | */ 15 | const path: `${string}.png`; 16 | export = path; 17 | } 18 | 19 | declare module "*.module.css" { 20 | /** 21 | * A record of class names to their corresponding CSS module classes 22 | */ 23 | const classes: { readonly [key: string]: string }; 24 | export = classes; 25 | } 26 | -------------------------------------------------------------------------------- /examples/cloudflare-prisma/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "allowImportingTsExtensions": true, 10 | "rewriteRelativeImportExtensions": true, 11 | "types": ["@cloudflare/workers-types"], 12 | "noEmit": true 13 | }, 14 | "include": ["src/**/*", "types/**/*", "alchemy.run.ts"], 15 | "references": [ 16 | { 17 | "path": "../../alchemy/tsconfig.json" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /alchemy/src/aws/account-id.ts: -------------------------------------------------------------------------------- 1 | import { importPeer } from "../util/peer.ts"; 2 | 3 | export type AccountId = string & { 4 | readonly __brand: "AccountId"; 5 | }; 6 | 7 | /** 8 | * Helper to get the current AWS account ID 9 | */ 10 | export async function AccountId(): Promise { 11 | const { GetCallerIdentityCommand, STSClient } = await importPeer( 12 | import("@aws-sdk/client-sts"), 13 | "aws::AccountId", 14 | ); 15 | const sts = new STSClient({}); 16 | const identity = await sts.send(new GetCallerIdentityCommand({})); 17 | return identity.Account! as AccountId; 18 | } 19 | -------------------------------------------------------------------------------- /alchemy/src/planetscale/organization.ts: -------------------------------------------------------------------------------- 1 | import { createPlanetScaleClient, type PlanetScaleProps } from "./api.ts"; 2 | import type { Organization } from "./api/types.gen.ts"; 3 | 4 | export type OrganizationRef = Organization; 5 | 6 | export async function OrganizationRef( 7 | name: string | Organization, 8 | options: PlanetScaleProps = {}, 9 | ) { 10 | const api = createPlanetScaleClient(options); 11 | const organization = await api.getOrganization({ 12 | path: { 13 | name: typeof name === "string" ? name : name.id, 14 | }, 15 | }); 16 | return organization.data; 17 | } 18 | -------------------------------------------------------------------------------- /example-monorepo/apps/analytics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "analytics", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "dev": "alchemy dev --adopt --app analytics", 7 | "deploy": "alchemy deploy --adopt --app analytics", 8 | "destroy": "alchemy destroy --app analytics", 9 | "check": "tsc --noEmit" 10 | }, 11 | "exports": { 12 | "./alchemy": { 13 | "bun": "./alchemy.run.ts", 14 | "import": "./lib/alchemy.run.js", 15 | "types": "./alchemy.run.ts" 16 | } 17 | }, 18 | "dependencies": { 19 | "alchemy": "catalog:" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /example-monorepo/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.com/schema.json", 3 | "ui": "tui", 4 | "tasks": { 5 | "deploy": { 6 | "dependsOn": ["^deploy"], 7 | "cache": false 8 | }, 9 | "dev": { 10 | "persistent": true, 11 | "cache": false 12 | }, 13 | "analytics#destroy": { 14 | "cache": false, 15 | "dependsOn": ["frontend#destroy"] 16 | }, 17 | "backend#destroy": { 18 | "cache": false, 19 | "dependsOn": ["frontend#destroy"] 20 | }, 21 | "frontend#destroy": { 22 | "cache": false 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /examples/cloudflare-container/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | # deliberately use an unset arg to ensure arg functionality works 4 | ARG IMAGE_VERSION 5 | 6 | FROM golang:${IMAGE_VERSION} AS build 7 | 8 | # Set destination for COPY 9 | WORKDIR /app 10 | 11 | # Download any Go modules 12 | COPY container_src/go.mod ./ 13 | RUN go mod download 14 | 15 | # Copy container source code 16 | COPY container_src/*.go ./ 17 | 18 | # Build 19 | RUN CGO_ENABLED=0 GOOS=linux go build -o /server 20 | 21 | FROM scratch 22 | COPY --from=build /server /server 23 | EXPOSE 8080 24 | 25 | # Run 26 | CMD ["/server"] -------------------------------------------------------------------------------- /examples/cloudflare-container/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "allowImportingTsExtensions": true, 10 | "rewriteRelativeImportExtensions": true, 11 | "types": ["@cloudflare/workers-types"], 12 | "noEmit": true 13 | }, 14 | "include": ["src/**/*", "types/**/*", "alchemy.run.ts", "e2e.ts"], 15 | "references": [ 16 | { 17 | "path": "../../alchemy/tsconfig.json" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /alchemy/test/handler.ts: -------------------------------------------------------------------------------- 1 | export async function handler(event: any) { 2 | console.log("Received event:", JSON.stringify(event)); 3 | 4 | // For Lambda URL, the actual payload is in the body 5 | const payload = event.body 6 | ? typeof event.body === "string" 7 | ? JSON.parse(event.body) 8 | : event.body 9 | : event; 10 | 11 | return { 12 | statusCode: 200, 13 | body: JSON.stringify({ 14 | message: "Hello from bundled handler!", 15 | event: payload, 16 | }), 17 | }; 18 | } 19 | // test case for handlers with _, 0-9, and A-Z 20 | export const _myHandler012 = handler; 21 | -------------------------------------------------------------------------------- /alchemy/src/fs/file-collection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Collection of files with their contents 3 | */ 4 | export type FileCollection = { 5 | /** 6 | * Type identifier for FileCollection 7 | */ 8 | type: "fs::FileCollection"; 9 | /** 10 | * Map of relative paths to file contents 11 | */ 12 | files: { 13 | [relativePath: string]: string; 14 | }; 15 | }; 16 | 17 | export function isFileCollection(value: unknown): value is FileCollection { 18 | return ( 19 | typeof value === "object" && 20 | value !== null && 21 | "type" in value && 22 | value.type === "fs::FileCollection" 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/app/routes/home.tsx: -------------------------------------------------------------------------------- 1 | import type { Route } from "./+types/home"; 2 | import { Welcome } from "../welcome/welcome"; 3 | 4 | export function meta({}: Route.MetaArgs) { 5 | return [ 6 | { title: "New React Router App" }, 7 | { name: "description", content: "Welcome to React Router!" }, 8 | ]; 9 | } 10 | 11 | export function loader({ context }: Route.LoaderArgs) { 12 | return { message: context.cloudflare.env.VALUE_FROM_CLOUDFLARE }; 13 | } 14 | 15 | export default function Home({ loaderData }: Route.ComponentProps) { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /alchemy/templates/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies (bun install) 2 | node_modules 3 | 4 | # output 5 | out 6 | dist 7 | *.tgz 8 | 9 | # code coverage 10 | coverage 11 | *.lcov 12 | 13 | # logs 14 | logs 15 | _.log 16 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 17 | 18 | # dotenv environment variable files 19 | .env 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | .env.local 24 | 25 | # caches 26 | .eslintcache 27 | .cache 28 | *.tsbuildinfo 29 | 30 | # IntelliJ based IDEs 31 | .idea 32 | 33 | # Finder (MacOS) folder config 34 | .DS_Store 35 | 36 | .alchemy/ 37 | .env 38 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/templates/typescript/_gitignore: -------------------------------------------------------------------------------- 1 | # dependencies (bun install) 2 | node_modules 3 | 4 | # output 5 | out 6 | dist 7 | *.tgz 8 | 9 | # code coverage 10 | coverage 11 | *.lcov 12 | 13 | # logs 14 | logs 15 | _.log 16 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 17 | 18 | # dotenv environment variable files 19 | .env 20 | .env.development.local 21 | .env.test.local 22 | .env.production.local 23 | .env.local 24 | 25 | # caches 26 | .eslintcache 27 | .cache 28 | *.tsbuildinfo 29 | 30 | # IntelliJ based IDEs 31 | .idea 32 | 33 | # Finder (MacOS) folder config 34 | .DS_Store 35 | 36 | .alchemy/ 37 | .env 38 | .wrangler/ -------------------------------------------------------------------------------- /alchemy/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.base.json", 3 | "include": ["package.json", "src/**/*.ts", "src/**/*.js", "src/**/*.tsx"], 4 | "compilerOptions": { 5 | "types": [], 6 | "composite": true, 7 | "noEmit": false, 8 | "outDir": "./lib", 9 | "rootDir": "./src", 10 | "sourceMap": true, 11 | "declarationMap": true, 12 | "declaration": true, 13 | "module": "Preserve", 14 | "moduleResolution": "Bundler", 15 | "target": "ESNext", 16 | "allowJs": true, 17 | "allowImportingTsExtensions": true, 18 | "rewriteRelativeImportExtensions": true 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /example-monorepo/apps/backend/alchemy.run.ts: -------------------------------------------------------------------------------- 1 | import alchemy from "alchemy"; 2 | import { D1Database, Worker } from "alchemy/cloudflare"; 3 | import path from "node:path"; 4 | 5 | const app = await alchemy("backend"); 6 | 7 | const db = await D1Database("db"); 8 | 9 | export const backend = await Worker("worker", { 10 | entrypoint: path.join(import.meta.dirname, "src", "index.ts"), 11 | bindings: { 12 | db, 13 | API_KEY: alchemy.secret.env.API_KEY, 14 | key: "value", 15 | }, 16 | }); 17 | 18 | if (import.meta.main) { 19 | console.log({ url: backend.url }); 20 | } 21 | 22 | await app.finalize(); 23 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/app/routes/home.tsx: -------------------------------------------------------------------------------- 1 | import { Welcome } from "../welcome/welcome"; 2 | import type { Route } from "./+types/home"; 3 | 4 | export function meta({}: Route.MetaArgs) { 5 | return [ 6 | { title: "New React Router App" }, 7 | { name: "description", content: "Welcome to React Router!" }, 8 | ]; 9 | } 10 | 11 | export function loader({ context }: Route.LoaderArgs) { 12 | return { message: context.cloudflare.env.ALCHEMY_TEST_VALUE }; 13 | } 14 | 15 | export default function Home({ loaderData }: Route.ComponentProps) { 16 | return ; 17 | } 18 | -------------------------------------------------------------------------------- /examples/cloudflare-redwood/src/db/seed.ts: -------------------------------------------------------------------------------- 1 | import { drizzle } from "drizzle-orm/d1"; 2 | import { defineScript } from "rwsdk/worker"; 3 | import { users } from "./schema.js"; 4 | 5 | export default defineScript(async ({ env }) => { 6 | const db = drizzle(env.DB); 7 | 8 | // Insert a user 9 | await db.insert(users).values({ 10 | name: "__change me__", 11 | email: "__change me__", 12 | }); 13 | 14 | // Verify the insert by selecting all users 15 | const result = await db.select().from(users).all(); 16 | 17 | console.log("🌱 Finished seeding"); 18 | 19 | return Response.json(result); 20 | }); 21 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-simple/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "allowImportingTsExtensions": true, 10 | "rewriteRelativeImportExtensions": true, 11 | "noEmit": true, 12 | "types": ["@cloudflare/workers-types"], 13 | }, 14 | "include": ["src/**/*", "types/**/*", "alchemy.run.ts", "e2e.test.ts"], 15 | "references": [ 16 | { 17 | "path": "../../alchemy/tsconfig.json" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /example-monorepo/apps/backend/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "backend", 3 | "private": true, 4 | "type": "module", 5 | "module": "./lib/src/index.js", 6 | "scripts": { 7 | "dev": "alchemy dev --adopt --app backend", 8 | "deploy": "alchemy deploy --adopt --app backend", 9 | "destroy": "alchemy destroy --app backend", 10 | "check": "tsc --noEmit" 11 | }, 12 | "exports": { 13 | "./alchemy": { 14 | "bun": "./alchemy.run.ts", 15 | "import": "./lib/alchemy.run.js", 16 | "types": "./alchemy.run.ts" 17 | } 18 | }, 19 | "dependencies": { 20 | "alchemy": "catalog:" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/src/livestore/server.ts: -------------------------------------------------------------------------------- 1 | import { makeDurableObject, makeWorker } from "@livestore/sync-cf/cf-worker"; 2 | 3 | export class WebSocketServer extends makeDurableObject({ 4 | onPush: async (message) => { 5 | console.log("onPush", message.batch); 6 | }, 7 | onPull: async (message) => { 8 | console.log("onPull", message); 9 | }, 10 | }) {} 11 | 12 | export default makeWorker({ 13 | validatePayload: (payload: any) => { 14 | if (payload?.authToken !== "insecure-token-change-me") { 15 | throw new Error("Invalid auth token"); 16 | } 17 | }, 18 | enableCORS: true, 19 | }); 20 | -------------------------------------------------------------------------------- /alchemy/bin/commands/deploy.ts: -------------------------------------------------------------------------------- 1 | import z from "zod"; 2 | import { 3 | adopt, 4 | entrypoint, 5 | execAlchemy, 6 | execArgs, 7 | force, 8 | watch, 9 | } from "../services/execute-alchemy.ts"; 10 | import { loggedProcedure } from "../trpc.ts"; 11 | 12 | export const deploy = loggedProcedure 13 | .meta({ 14 | description: "deploy an alchemy project", 15 | }) 16 | .input( 17 | z.tuple([ 18 | entrypoint, 19 | z.object({ 20 | ...execArgs, 21 | force, 22 | watch, 23 | adopt, 24 | }), 25 | ]), 26 | ) 27 | .mutation(async ({ input }) => execAlchemy(...input)); 28 | -------------------------------------------------------------------------------- /alchemy/templates/react-router/workers/app.ts: -------------------------------------------------------------------------------- 1 | import { createRequestHandler } from "react-router"; 2 | 3 | declare module "react-router" { 4 | export interface AppLoadContext { 5 | cloudflare: { 6 | env: Env; 7 | ctx: ExecutionContext; 8 | }; 9 | } 10 | } 11 | 12 | const requestHandler = createRequestHandler( 13 | () => import("virtual:react-router/server-build"), 14 | import.meta.env.MODE, 15 | ); 16 | 17 | export default { 18 | async fetch(request: Request, env: Env, ctx: ExecutionContext) { 19 | return requestHandler(request, { 20 | cloudflare: { env, ctx }, 21 | }); 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /examples/cloudflare-react-router/workers/app.ts: -------------------------------------------------------------------------------- 1 | import { createRequestHandler } from "react-router"; 2 | 3 | declare module "react-router" { 4 | export interface AppLoadContext { 5 | cloudflare: { 6 | env: Env; 7 | ctx: ExecutionContext; 8 | }; 9 | } 10 | } 11 | 12 | const requestHandler = createRequestHandler( 13 | () => import("virtual:react-router/server-build"), 14 | import.meta.env.MODE, 15 | ); 16 | 17 | export default { 18 | async fetch(request: Request, env: Env, ctx: ExecutionContext) { 19 | return requestHandler(request, { 20 | cloudflare: { env, ctx }, 21 | }); 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/astro/plugin.ts: -------------------------------------------------------------------------------- 1 | import cloudflare, { type Options } from "@astrojs/cloudflare"; 2 | import type { AstroIntegration } from "astro"; 3 | import { getPlatformProxyOptions } from "../cloudflare-env-proxy.ts"; 4 | 5 | const isAstroCheck = 6 | !!process.argv.find((arg) => arg.includes("astro")) && 7 | process.argv.includes("check"); 8 | 9 | const alchemy = (options?: Options): AstroIntegration => { 10 | return cloudflare({ 11 | platformProxy: getPlatformProxyOptions( 12 | options?.platformProxy, 13 | !isAstroCheck, 14 | ), 15 | ...options, 16 | }); 17 | }; 18 | 19 | export default alchemy; 20 | -------------------------------------------------------------------------------- /examples/cloudflare-sveltekit/svelte.config.js: -------------------------------------------------------------------------------- 1 | import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; 2 | import alchemy from "alchemy/cloudflare/sveltekit"; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://svelte.dev/docs/kit/integrations 7 | // for more information about preprocessors 8 | preprocess: vitePreprocess(), 9 | 10 | kit: { 11 | // Using Alchemy adapter for deployment to Cloudflare Workers 12 | // See https://svelte.dev/docs/kit/adapters for more information about adapters. 13 | adapter: alchemy(), 14 | }, 15 | }; 16 | 17 | export default config; 18 | -------------------------------------------------------------------------------- /examples/cloudflare-livestore/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | TodoMVC + LiveStore 4 | 5 | 13 | 14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /examples/cloudflare-nextjs/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | :root { 4 | --background: #ffffff; 5 | --foreground: #171717; 6 | } 7 | 8 | @theme inline { 9 | --color-background: var(--background); 10 | --color-foreground: var(--foreground); 11 | --font-sans: var(--font-geist-sans); 12 | --font-mono: var(--font-geist-mono); 13 | } 14 | 15 | @media (prefers-color-scheme: dark) { 16 | :root { 17 | --background: #0a0a0a; 18 | --foreground: #ededed; 19 | } 20 | } 21 | 22 | body { 23 | background: var(--background); 24 | color: var(--foreground); 25 | font-family: Arial, Helvetica, sans-serif; 26 | } 27 | -------------------------------------------------------------------------------- /alchemy/bin/commands/run.ts: -------------------------------------------------------------------------------- 1 | import z from "zod"; 2 | import { 3 | entrypoint, 4 | execAlchemy, 5 | execArgs, 6 | watch, 7 | } from "../services/execute-alchemy.ts"; 8 | import { loggedProcedure } from "../trpc.ts"; 9 | 10 | export const run = loggedProcedure 11 | .meta({ 12 | description: "run alchemy in read-only mode", 13 | }) 14 | .input( 15 | z.tuple([ 16 | entrypoint, 17 | z.object({ 18 | ...execArgs, 19 | watch, 20 | }), 21 | ]), 22 | ) 23 | .mutation(async ({ input: [main, options] }) => 24 | execAlchemy(main, { 25 | ...options, 26 | read: true, 27 | }), 28 | ); 29 | -------------------------------------------------------------------------------- /alchemy/templates/tanstack-start/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "TanStack App", 3 | "name": "Create TanStack App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/cloudflare-durable-object-websocket/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "module": "ESNext", 5 | "moduleResolution": "Bundler", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "allowImportingTsExtensions": true, 10 | "rewriteRelativeImportExtensions": true, 11 | "types": ["@cloudflare/workers-types", "./types/cf.d.ts"], 12 | "noEmit": true 13 | }, 14 | "include": ["alchemy.run.ts", "src", "types"], 15 | "references": [ 16 | { 17 | "path": "../../alchemy/tsconfig.json" 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /examples/cloudflare-tanstack-start/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "TanStack App", 3 | "name": "Create TanStack App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /examples/cloudflare-worker-simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-worker-simple", 3 | "version": "0.0.0", 4 | "description": "Alchemy Typescript Project", 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc -b", 8 | "deploy": "alchemy deploy --env-file ../../.env", 9 | "destroy": "alchemy destroy --env-file ../../.env", 10 | "dev": "alchemy dev --env-file ../../.env" 11 | }, 12 | "devDependencies": { 13 | "@cloudflare/workers-types": "catalog:", 14 | "@types/node": "^24.0.1", 15 | "alchemy": "workspace:*", 16 | "typescript": "catalog:" 17 | }, 18 | "dependencies": { 19 | "hono": "^4.9.10" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /alchemy-web/src/components/MarkdownContent.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import BlogMarkdownContent from 'starlight-blog/components/MarkdownContent.astro'; 3 | import NovaMarkdownContent from 'starlight-theme-nova/components/MarkdownContent.astro'; 4 | 5 | const props = Astro.props; 6 | // Check if it's a blog post (not just /blog/ landing page) 7 | const pathname = Astro.url.pathname; 8 | const isBlogPost = pathname.startsWith('/blog/') && pathname !== '/blog/'; 9 | --- 10 | 11 | {isBlogPost ? ( 12 | 13 | 14 | 15 | ) : ( 16 | 17 | 18 | 19 | )} 20 | -------------------------------------------------------------------------------- /alchemy/src/llms.ts: -------------------------------------------------------------------------------- 1 | import fs from "node:fs/promises"; 2 | import path from "pathe"; 3 | 4 | export interface AlchemyRule { 5 | name: string; 6 | rule: string; 7 | description?: string; 8 | alwaysApply?: boolean; 9 | globs?: string | string[]; 10 | } 11 | 12 | const alchemy: AlchemyRule = { 13 | name: "cloudflare", 14 | description: "Core Alchemy development guidelines and patterns", 15 | alwaysApply: true, 16 | globs: ["*.ts"], 17 | rule: await fs.readFile( 18 | path.join(import.meta.dirname, "llms.cloudflare.txt"), 19 | "utf-8", 20 | ), 21 | }; 22 | 23 | const alchemyRules: AlchemyRule[] = [alchemy]; 24 | 25 | export default alchemyRules; 26 | -------------------------------------------------------------------------------- /examples/cloudflare-container/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-container", 3 | "version": "0.0.0", 4 | "description": "Alchemy Typescript Project", 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc -b", 8 | "deploy": "alchemy deploy --env-file ../../.env", 9 | "destroy": "alchemy destroy --env-file ../../.env", 10 | "dev": "alchemy dev --env-file ../../.env" 11 | }, 12 | "devDependencies": { 13 | "@cloudflare/containers": "catalog:", 14 | "@cloudflare/workers-types": "catalog:", 15 | "@types/node": "^24.0.1", 16 | "alchemy": "workspace:*", 17 | "hono": "^4.8.3", 18 | "typescript": "catalog:" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /alchemy/templates/astro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "name": "@alchemy.run/astro-template", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "astro": "astro", 7 | "build": "astro check && astro build", 8 | "deploy": "alchemy deploy", 9 | "destroy": "alchemy destroy", 10 | "dev": "alchemy dev", 11 | "preview": "astro preview" 12 | }, 13 | "dependencies": { 14 | "astro": "^5.10.0" 15 | }, 16 | "devDependencies": { 17 | "alchemy": "workspace:*", 18 | "@astrojs/cloudflare": "^12.6.0", 19 | "miniflare": "^4.20250617.3", 20 | "@cloudflare/workers-types": "^4.20250805.0", 21 | "typescript": "^5.8.3" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /alchemy/test/cloudflare/bundle-handler.ts: -------------------------------------------------------------------------------- 1 | import { initLogger } from "braintrust"; 2 | import crypto from "crypto"; 3 | import debug from "debug"; 4 | import crypto2 from "node:crypto"; 5 | 6 | export default { 7 | async fetch(_request: Request, env: any): Promise { 8 | const logger = initLogger({ 9 | projectName: "My Project", 10 | apiKey: env.BRAINTRUST_API_KEY, 11 | asyncFlush: false, 12 | }); 13 | console.log(crypto.randomBytes(10)); 14 | console.log(crypto2.randomBytes(10)); 15 | console.log(logger); 16 | console.log(typeof debug); 17 | require("ws"); 18 | return new Response("Hello World!"); 19 | }, 20 | }; 21 | -------------------------------------------------------------------------------- /alchemy/src/cloudflare/react-router/plugin.ts: -------------------------------------------------------------------------------- 1 | import type { PluginConfig } from "@cloudflare/vite-plugin"; 2 | import type { PluginOption } from "vite"; 3 | import alchemyVite from "../vite/plugin.ts"; 4 | 5 | const alchemy = (config: PluginConfig = {}): PluginOption => { 6 | // plugin is not required for react-router typegen, so return a no-op to avoid errors 7 | if ( 8 | process.argv.some((arg) => arg.includes("react-router")) && 9 | process.argv.includes("typegen") 10 | ) { 11 | return null; 12 | } 13 | return alchemyVite({ 14 | viteEnvironment: { 15 | name: "ssr", 16 | }, 17 | ...config, 18 | }); 19 | }; 20 | 21 | export default alchemy; 22 | -------------------------------------------------------------------------------- /alchemy/templates/astro/src/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | import type { APIRoute } from "astro"; 2 | 3 | export const GET: APIRoute = async ({ request }) => { 4 | // Access Cloudflare runtime context 5 | const runtime = request.cf; 6 | 7 | return new Response( 8 | JSON.stringify({ 9 | message: "Hello from Astro API on Cloudflare!", 10 | timestamp: new Date().toISOString(), 11 | colo: runtime?.colo || "unknown", 12 | country: runtime?.country || "unknown", 13 | city: runtime?.city || "unknown", 14 | }), 15 | { 16 | status: 200, 17 | headers: { 18 | "Content-Type": "application/json", 19 | }, 20 | }, 21 | ); 22 | }; 23 | -------------------------------------------------------------------------------- /examples/cloudflare-astro/src/pages/api/hello.ts: -------------------------------------------------------------------------------- 1 | import type { APIRoute } from "astro"; 2 | 3 | export const GET: APIRoute = async ({ request }) => { 4 | // Access Cloudflare runtime context 5 | const runtime = request.cf; 6 | 7 | return new Response( 8 | JSON.stringify({ 9 | message: "Hello from Astro API on Cloudflare!", 10 | timestamp: new Date().toISOString(), 11 | colo: runtime?.colo || "unknown", 12 | country: runtime?.country || "unknown", 13 | city: runtime?.city || "unknown", 14 | }), 15 | { 16 | status: 200, 17 | headers: { 18 | "Content-Type": "application/json", 19 | }, 20 | }, 21 | ); 22 | }; 23 | --------------------------------------------------------------------------------