Cloudflare Workers
adapter-cloudflare, the two compatibility flags the runtime needs, static assets, custom domains and a deploy workflow.
This is the setup the demo and the docs site use.
#svelte.config.js
import adapter from '@sveltejs/adapter-cloudflare';
export default nornsConfig({
// ...preprocess
kit: { adapter: adapter() }
});#wrangler.toml
name = "my-app"
main = ".svelte-kit/cloudflare/_worker.js"
compatibility_date = "2026-04-01"
compatibility_flags = ["nodejs_als", "nodejs_compat"]
routes = [
{ pattern = "my-app.example.com", custom_domain = true }
]
[assets]
directory = ".svelte-kit/cloudflare"
binding = "ASSETS"
[observability]
enabled = trueThe two compatibility flags are not optional:
nodejs_alsprovidesAsyncLocalStorage, which the request scope is built on.nodejs_compatis the general Node compatibility layer that Drizzle drivers and many libraries need.
custom_domain = true works when the zone is on Cloudflare; Workers issues the certificate. Otherwise point a CNAME at the workers.dev hostname.
Add a [[d1_databases]] block for a database; see Cloudflare D1.
#Local development
vite dev gets event.platform from the adapter's platform proxy, which reads wrangler.toml and keeps local state under .wrangler/state/. No account is needed to run locally. Add .wrangler/ to .gitignore.
#Deploying
bun run build && wrangler deployA GitHub Actions workflow that lints, checks, builds and deploys on every push to main:
name: Deploy
on:
push:
branches: [main]
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v2
- run: bun install
- run: bun run lint
- run: bun run check
- run: bun run build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
packageManager: bun
command: deployThe token needs Workers Scripts: Edit (and D1: Edit when the workflow applies migrations). Keep it in repository secrets, never in wrangler.toml.
#Prerendering
A fully prerendered app (like this documentation site) still produces a worker, but every page lands in the assets directory and the worker only runs for misses. Set export prerender := true in the root +layout.c.