Cloudflare
Cloudflare Workers
Preset: cloudflare_module
The following shows an example nitro.config.ts file for deploying a Nitro app to Cloudflare Workers.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module"
})
Local Preview
You can use Wrangler to preview your app locally:
npm run build
yarn build
pnpm build
bun run build
deno run build
npx wrangler dev
yarn dlx wrangler dev
pnpm dlx wrangler dev
bunx wrangler dev
deno run -A npm:wrangler dev
Manual Deploy
After building your application you can manually deploy it with Wrangler.
First make sure to be logged into your Cloudflare account:
npx wrangler login
yarn dlx wrangler login
pnpm dlx wrangler login
bunx wrangler login
deno run -A npm:wrangler login
Then you can deploy the application with:
npx wrangler deploy
yarn dlx wrangler deploy
pnpm dlx wrangler deploy
bunx wrangler deploy
deno run -A npm:wrangler deploy
Runtime Hooks
You can use the runtime hooks below to extend Worker handlers.
cloudflare:scheduledcloudflare:emailcloudflare:queuecloudflare:tailcloudflare:tracecloudflare:durable:init(only with thecloudflare_durablepreset)cloudflare:durable:alarm(only with thecloudflare_durablepreset)
cloudflare:queue hook receives the message batch as batch and the cloudflare:email hook receives the incoming message as message. The older event field is deprecated for both hooks.Additional Exports
You can add an exports.cloudflare.ts file to your project root to export additional handlers or properties from the Cloudflare Worker entrypoint.
export class MyWorkflow extends WorkflowEntrypoint {
async run(event: WorkflowEvent, step: WorkflowStep) {
// ...
}
}
Nitro will automatically detect this file and include its exports in the final build.
exports.cloudflare.ts file must not have a default export.You can also customize the entrypoint file location using the cloudflare.exports option in your nitro.config.ts:
import { defineConfig } from "nitro";
export default defineConfig({
cloudflare: {
exports: "custom-exports-entry.ts"
}
})
Scheduled Tasks (Cron Triggers)
When using Nitro tasks with scheduledTasks, Nitro automatically generates Cron Triggers in the wrangler config at build time.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
experimental: {
tasks: true,
},
scheduledTasks: {
"* * * * *": ["cms:update"],
"0 15 1 * *": ["db:cleanup"],
}
})
No manual Wrangler configuration is needed — Nitro handles it for you.
Cloudflare Workers with Durable Objects
Preset: cloudflare_durable
This preset extends cloudflare_module and routes requests through a Durable Object instance, enabling stateful features such as WebSocket support (via CrossWS) and in-memory state that persists across requests.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_durable"
})
The preset entry exports a $DurableObject class. You need to declare the Durable Object binding and migration in your wrangler config:
{
"durable_objects": {
"bindings": [
{
"name": "$DurableObject",
"class_name": "$DurableObject"
}
]
},
"migrations": [
{
"tag": "v1",
"new_classes": ["$DurableObject"]
}
]
}
You can use the cloudflare:durable:init runtime hook to run code when the Durable Object is initialized, and the cloudflare:durable:alarm hook to handle alarms.
Cloudflare Pages
Preset: cloudflare_pages
The following shows an example nitro.config.ts file for deploying a Nitro app to Cloudflare Pages.
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_pages"
})
Nitro automatically generates a _routes.json file that controls which routes get served from files and which are served from the Worker script. The auto-generated routes file can be overridden with the config option cloudflare.pages.routes (read more).
Local Preview
You can use Wrangler to preview your app locally:
npm run build
yarn build
pnpm build
bun run build
deno run build
npx wrangler pages dev
yarn dlx wrangler pages dev
pnpm dlx wrangler pages dev
bunx wrangler pages dev
deno run -A npm:wrangler pages dev
Manual Deploy
After building your application you can manually deploy it with Wrangler.
First make sure to be logged into your Cloudflare account:
npx wrangler login
yarn dlx wrangler login
pnpm dlx wrangler login
bunx wrangler login
deno run -A npm:wrangler login
Then you can deploy the application with:
npx wrangler pages deploy
yarn dlx wrangler pages deploy
pnpm dlx wrangler pages deploy
bunx wrangler pages deploy
deno run -A npm:wrangler pages deploy
Deploy within CI/CD using GitHub Actions
Regardless of whether you're using Cloudflare Pages or Cloudflare Workers, you can use the Wrangler GitHub actions to deploy your application.
cloudflare_pages.Environment Variables
Nitro allows you to universally access environment variables using process.env, import.meta.env, or the runtime config.
Example: If you have set the SECRET and NITRO_HELLO_THERE environment variables, you can access them in the following ways:
import { defineHandler } from "nitro";
import { useRuntimeConfig } from "nitro/runtime-config";
console.log(process.env.SECRET) // note that this is in the global scope! so it doesn't actually work and the variable is undefined!
export default defineHandler((event) => {
// note that all the below are valid ways of accessing the above mentioned variables
useRuntimeConfig().helloThere
useRuntimeConfig().secret
process.env.NITRO_HELLO_THERE
import.meta.env.SECRET
});
Specify Variables in Development Mode
For development, you can use a .env or .env.local file to specify environment variables:
NITRO_HELLO_THERE="captain"
SECRET="top-secret"
.env and .env.local to your .gitignore file so that you don't commit them, as they can contain sensitive information.Specify Variables for local previews
After building, when you try out your project locally with wrangler dev or wrangler pages dev, specify environment variables in a .dev.vars file in the root of your project (as described in the Pages and Workers documentation).
If you are using a .env or .env.local file while developing, your .dev.vars should be identical to it.
.dev.vars to your .gitignore file so that you don't commit it, as it can contain sensitive information.Specify Variables for Production
For production, use the Cloudflare dashboard or the wrangler secret command to set environment variables and secrets.
Specify Variables using wrangler.toml/wrangler.json
You can specify a custom wrangler.toml/wrangler.json file and define vars inside.
Example:
# Shared
[vars]
NITRO_HELLO_THERE="general"
SECRET="secret"
# Override values for `--env production` usage
[env.production.vars]
NITRO_HELLO_THERE="captain"
SECRET="top-secret"
{
"vars": {
"NITRO_HELLO_THERE": "general",
"SECRET": "secret"
},
"env": {
"production": {
"vars": {
"NITRO_HELLO_THERE": "captain",
"SECRET": "top-secret"
}
}
}
}
Direct access to Cloudflare bindings
Bindings let you interact with resources from the Cloudflare platform, such as key-value data storage (KV) and serverless SQL databases (D1).
At runtime, you can access bindings from the request event via event.req.runtime.cloudflare.env. For example, this is how you can access a D1 binding:
import { defineHandler } from "nitro";
defineHandler(async (event) => {
const { env } = event.req.runtime.cloudflare
const stmt = await env.MY_D1.prepare('SELECT id FROM table')
const { results } = await stmt.all()
})
Access to the bindings in local dev
In development mode, Nitro emulates the Cloudflare environment using Miniflare (the same workerd runtime used by Wrangler and Cloudflare Workers in production). This means bindings are available natively from the request event — no separate proxy or wrangler installation is required.
To access bindings in dev mode, first define them. You can do this in a wrangler.jsonc/wrangler.json/wrangler.toml file:
[vars]
MY_VARIABLE="my-value"
[[kv_namespaces]]
binding = "MY_KV"
id = "xxx"
{
"vars": {
"MY_VARIABLE": "my-value",
},
"kv_namespaces": [
{
"binding": "MY_KV",
"id": "xxx"
}
]
}
Alternatively, you can define bindings inline in your nitro.config.ts using the cloudflare.wrangler option (it accepts the same shape as wrangler.json):
import { defineConfig } from "nitro";
export default defineConfig({
preset: "cloudflare_module",
cloudflare: {
wrangler: {
vars: {
MY_VARIABLE: "my-value",
},
kv_namespaces: [{ binding: "MY_KV", id: "xxx" }],
},
},
})
From now on, when running
npm run dev
yarn dev
pnpm dev
bun run dev
deno run dev
you can access MY_VARIABLE and MY_KV from the request event as illustrated above.
Wrangler environments
If you have multiple Wrangler environments, you can specify which one to use during local dev emulation with the cloudflare.wranglerEnv option:
import { defineConfig } from "nitro";
export default defineConfig({
preset: 'cloudflare_module',
cloudflare: {
wranglerEnv: 'preview'
}
})