Edit this page

Cloudflare

We recommend using vike-cloudflare to deploy your app to Cloudflare.

Go to vike.dev/new if you want to scaffold a new Vike app that uses vike-cloudflare.

vike-cloudflare

Version history: CHANGELOG.md
Examples: vike.dev/new and examples/
Source code: GitHub > vikejs/vike-cloudflare
npm package: vike-cloudflare

You can use Vike with the vike-cloudflare extension for a zero-config Cloudflare deployment of your SSR or pre-rendered (aka SSG) app.

See:

With server

npm i vike-cloudflare wrangler cross-env
// pages/+config.ts
 
import type { Config } from 'vike/types'
import vikeCloudflare from 'vike-cloudflare/config'
 
export default {
  extends: [vikeCloudflare],
  server: 'server/index.ts'
} satisfies Config

If you have vike-server installed then remove it (replace it with vike-cloudflare).

// server/index.ts
 
import { Hono } from 'hono'
import { apply } from 'vike-cloudflare/hono'
import { serve } from 'vike-cloudflare/hono/serve'
 
function startServer() {
  const app = new Hono()
  apply(app)
  return serve(app, { port: 3000 })
}
 
export default startServer()

If you haven't already, set up a Hono server and install the hono package.

vike-cloudflare currently only supports Hono and Hattip — more servers are coming soon.

// package.json
 
{
  "scripts": {
    "dev": "vike dev",
    "preview": "vike build && wrangler pages dev",
    "deploy": "vike build && wrangler pages deploy"
  }
}
// wrangler.jsonc
 
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "compatibility_date": "2025-08-06",
  "name": "my-vike-cloudflare-app",
  "pages_build_output_dir": "./dist/cloudflare",
  // Only needed if your app (or one of your libraries) uses Node.js APIs
  "compatibility_flags": ["nodejs_compat"]
}
# .gitignore
 
.wrangler/

Without server

npm i vike-cloudflare wrangler cross-env
// pages/+config.ts
 
import type { Config } from 'vike/types'
import vikeCloudflare from 'vike-cloudflare/config'
 
export default {
  prerender: true,
  extends: [vikeCloudflare]
} satisfies Config
// package.json
 
{
  "scripts": {
    "dev": "vike dev",
    "preview": "vike build && wrangler pages dev",
    "deploy": "vike build && wrangler pages deploy"
  }
}
// wangler.jsonc
 
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "compatibility_date": "2025-08-06",
  "name": "my-vike-cloudflare-app",
  "pages_build_output_dir": "./dist/cloudflare",
  "assets": {
    "directory": "./dist/cloudflare"
  }
}
# .gitignore
 
.wrangler/

Cloudflare APIs

You can access Cloudflare's APIs (such as D1 and KV):

Using +onCreateGlobalContext.server, you can make Cloudflare's bindings (the env object) available anywhere via globalContext.cloudflare.env.

// pages/+onCreateGlobalContext.server.ts
 
export { onCreateGlobalContext }
 
import type { GlobalContextServer } from 'vike/types'
 
async function onCreateGlobalContext(globalContext: GlobalContextServer) {
  let cloudflare: { env: Cloudflare.Env }
  if (import.meta.env.DEV) {
    const { getPlatformProxy } = await import('wrangler')
    cloudflare = (await getPlatformProxy()) as any
  } else {
    cloudflare = await import('cloudflare:workers')
  }
  globalContext.cloudflare = cloudflare
}
 
declare global {
  namespace Vike {
    interface GlobalContextServer {
      cloudflare: { env: Cloudflare.Env }
    }
  }
}
// vite.config.ts
 
import { defineConfig } from 'vite'
 
export default defineConfig({
  build: {
    rollupOptions: {
      external: ['cloudflare:workers']
    }
  }
})

For an example of how to access Cloudflare D1 during development, see:

npm create vike@latest --- --react --hono --drizzle --cloudflare

Or go to vike.dev/new and select Cloudflare with an ORM.

TypeScript

If you use TypeScript, (re-)run wrangler types after changing your Cloudflare configuration to generate/update the worker-configuration.d.ts file.

npx wrangler types

Then commit it:

git commit -am "update cloudflare types"

Make sure TypeScript loads it:

// tsconfig.json
 
{
  "compilerOptions": {
    "types": ["./worker-configuration.d.ts"],
 }
}

See also: Cloudflare Workers > TypeScript

Extend 3MB limit

By default the bundle size of your worker cannot exceed 3MB, but you can request sizes of up to 100MB and beyond.

Manual integration

Instead of using vike-cloudflare, you can manually integrate your app with Cloudflare yourself.

Cloudflare Pages

For a manual integration, we generally recommend using:

Examples:

Wrangler

You can also directly use Cloudflare Workers instead of using Cloudflare Pages.

Cloudflare Workers requires your entire worker code to be bundled into a single file — you can use Wrangler to achieve that (it uses esbuild under the hood).

Cloudflare uses the term "worker code" to denote server code that is run on its edge infrastructure.

Examples:

Development

For a significantly faster development experience we recommend, whenever possible, using Vite's development server (or a server such as Express.js or Hono) instead of Wrangler.

In other words:

  • Skip wrangler / Cloudflare Workers altogether while developing your app.
  • Use wrangler dev to preview your worker.
  • Use wrangler publish to deploy your worker to Cloudflare Workers.

Examples:

Universal fetch()

When using Node.js(/Bun/Deno) for development and Cloudflare Workers for production, you may need a fetch() function that works in both environments.

You can define a fetch function at pageContext.fetch that works in all environments. The trick is to add a different fetch() implementation to pageContextInit at renderPage(pageContextInit).

Example: /examples/cloudflare-workers-react-full#universal-fetch.

Libraries such as node-fetch or cross-fetch typically don't work with Cloudflare Workers.

See also