A starter for TypeScript apps on Cloudflare, built with Effect 4, Foldkit, Bun, mise, and Alchemy v2.
It comes with a Foldkit counter page, a small Effect service, a GET /api/health route, and an Alchemy stack with two Workers: a Website that serves the UI and an API. Both Workers send logs and traces to Workers Observability, and the API's Effect spans show up in Cloudflare's trace view.
mise trust && mise install
mise run check
mise run build
mise run devmise run dev prints a Website URL. The UI is served there, and /api/* is forwarded to the API Worker, which also has its own workers.dev URL. GET /api/health returns { "name": "Project starter", "status": "ok" }. Unknown API routes return a JSON 404.
alchemy.run.ts re-exports the platform stack
src/
model.ts / service.ts portable Schema and Effect service
api.ts / api.test.ts routes and HTTP contract tests
platform/
boundary.test.ts keeps platform imports out of domain code
cloudflare/{stack,api,edge}.ts resources, API Worker, forwarding edge
ui/
entry.ts runtime boot
main.ts Model, Messages, init, update, view
styles.css light/dark Tailwind theme
components/ui/ foldcn badge, bubble, button, empty,
input, message, and textarea
lib/utils.ts `cn` class helper
story.test.ts / scene.test.ts update and view tests
AGENTS.md Foldkit conventions
Root files configure Bun, mise, TypeScript, Vite, Oxlint/Oxfmt, foldcn, the Foldkit DevTools MCP server, and dependency patches.
- Click Use this template → Create a new repository and pick the new repository's visibility.
- Decide on the product's domain names, who owns which data, how users authenticate, and whether you need D1, Durable Objects, or AI.
- Rename things:
nameinpackage.json, theproject-starterstack insrc/platform/cloudflare/stack.ts, the app name insrc/platform/cloudflare/api.ts, and the page title and content inindex.htmlandsrc/ui/. Resource names stick once deployed, so settle them before the first deploy. - Run
mise trust && mise install. It installs Bun and the locked dependencies. Commitbun.lock. Read the tooling guide before upgrading dependencies. - Replace the sample service and counter with your first real feature. Keep Cloudflare code in
src/platform/cloudflare/and runtime boot insrc/ui/entry.ts. - Add your product's invariants to
AGENTS.md, rewrite this README, and run the checks.
A prompt for an agent: "Read AGENTS.md and docs/. Adapt this starter for an application that does [product description]. Keep the stack and boundaries. Build one useful vertical slice and verify it locally. Do not deploy."
Set up a Cloudflare profile with mise run cloudflare:profile, or point ALCHEMY_PROFILE at an existing one. mise run deploy deploys the prod stage. The first deploy may offer to create Cloudflare-hosted Alchemy state.
Both Workers are public. The API answers on its workers.dev URL and through the Website's service binding, so any authentication you add has to cover both.
Both Workers persist invocation logs and traces with a sampling rate of 1, so every request is recorded. The API also provides Cloudflare.Telemetry({ headSamplingRate: 1, persist: true }), which exports the Api.request span and any Effect.withSpan or Effect.fn spans to Cloudflare.
After a deploy, request /api/health and open Workers & Pages → App / Api → Observability. Lower the sampling rates in stack.ts and api.ts once traffic grows. The Cloudflare guide has the details.
| Guide | Covers |
|---|---|
| Organization | Where code goes as the project grows |
| Architecture | Domains, services and layers, lifetimes, transactions |
| Tooling | Pinned versions, config files, commands, patches, AI |
| Cloudflare | Alchemy phases, Worker topology, telemetry, state, D1 |
| Guardrails | Boundaries, security, verification, what needs approval |
| Agent instructions | Rules for agents working in this repo |
| UI agent instructions | Foldkit architecture, testing, components, upgrades |
| Dependency patches | Alchemy and Foldkit DevTools fixes |