The @cloudflare/vite-plugin-cloudflare package provides a Vite plugin for developing Cloudflare Workers and Pages applications with Vite’s development server and build tooling.
Installation
npm install -D @cloudflare/vite-plugin-cloudflare
Basic Usage
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [ cloudflare ()] ,
}) ;
Plugin Configuration
cloudflare(config?)
Creates the Cloudflare Vite plugin.
Plugin configuration options Show PluginConfig properties
Path to Wrangler configuration file (defaults to auto-discovery) cloudflare ({
configPath: "./wrangler.toml" ,
})
Customize Worker configuration programmatically cloudflare ({
config ( workerConfig ) {
// Mutate config in place
workerConfig . compatibility_date = "2024-01-01" ;
},
})
// Or return a partial config to merge
cloudflare ({
config: {
name: "my-worker" ,
compatibility_flags: [ "nodejs_compat" ],
},
})
Show WorkerConfigCustomizer types
type WorkerConfigCustomizer =
| Partial < WorkerConfig >
| (( config : WorkerConfig ) => Partial < WorkerConfig > | void );
persistState
boolean | { path: string }
default: "true"
Control state persistence for local development // Disable persistence
cloudflare ({ persistState: false })
// Custom path
cloudflare ({ persistState: { path: "./.dev" } })
Port for Chrome DevTools inspector, or false to disable cloudflare ({ inspectorPort: 9229 })
Enable remote bindings during preview cloudflare ({ remoteBindings: false })
Additional workers to run alongside the main worker cloudflare ({
auxiliaryWorkers: [
{
configPath: "./workers/auth/wrangler.toml" ,
viteEnvironment: { name: "auth" },
},
{
config: {
name: "api" ,
main: "./workers/api/index.ts" ,
},
viteEnvironment: { name: "api" },
},
],
})
Show AuxiliaryWorkerConfig
Path to Wrangler config for this worker
Inline or customized worker config
Vite environment name for this worker
Experimental features Show Experimental options
headersAndRedirectsDevModeSupport
Support for _headers and _redirects files in dev mode cloudflare ({
experimental: {
headersAndRedirectsDevModeSupport: true ,
},
})
Dedicated worker for prerendering cloudflare ({
experimental: {
prerenderWorker: {
configPath: "./workers/prerender/wrangler.toml" ,
},
},
})
Array of Vite plugins (the plugin returns multiple internal plugins)
Worker Configuration
WorkerConfig
The Worker configuration object extends Wrangler’s configuration with Vite-specific options.
Show WorkerConfig properties (subset)
Workers Assets configuration
See Configuration Schema for the complete reference.
Utilities
getLocalWorkerdCompatibilityDate()
Get the recommended compatibility date for the local workerd version.
import { getLocalWorkerdCompatibilityDate } from "@cloudflare/vite-plugin-cloudflare" ;
const { date } = getLocalWorkerdCompatibilityDate ();
console . log ( date ); // "2024-01-01"
Object containing the recommended compatibility date
Development Examples
Basic Worker
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
configPath: "./wrangler.toml" ,
}),
] ,
}) ;
// src/index.ts
export default {
async fetch ( request , env , ctx ) {
return new Response ( "Hello from Vite + Cloudflare!" );
} ,
} ;
With Environment Overrides
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
configPath: "./wrangler.toml" ,
config ( workerConfig ) {
// Add development-only bindings
if ( process . env . NODE_ENV === "development" ) {
workerConfig . vars = {
... workerConfig . vars ,
DEBUG: "true" ,
};
}
},
}),
] ,
}) ;
Multi-Worker Setup
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
// Main worker
configPath: "./wrangler.toml" ,
viteEnvironment: {
name: "main" ,
},
// Auxiliary workers
auxiliaryWorkers: [
{
configPath: "./workers/auth/wrangler.toml" ,
viteEnvironment: { name: "auth" },
},
{
configPath: "./workers/api/wrangler.toml" ,
viteEnvironment: { name: "api" },
},
],
}),
] ,
}) ;
// src/index.ts (main worker)
export default {
async fetch ( request , env , ctx ) {
// Call auxiliary worker via service binding
const authResponse = await env . AUTH_SERVICE . fetch ( request );
if ( ! authResponse . ok ) {
return new Response ( "Unauthorized" , { status: 401 });
}
return new Response ( "Authenticated!" );
} ,
} ;
With Custom Persistence
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
persistState: {
path: "./.dev/state" ,
},
}),
] ,
}) ;
Pages Project
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
config: {
name: "my-pages-project" ,
compatibility_date: "2024-01-01" ,
assets: {
directory: "./public" ,
},
},
}),
] ,
}) ;
With Inspector
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
inspectorPort: 9229 ,
}),
] ,
}) ;
Then connect Chrome DevTools to chrome://inspect.
Build Configuration
The plugin automatically configures Vite for Workers compatibility:
Sets ssr.target to "webworker"
Configures resolve conditions: ["workerd", "worker", "browser"]
Handles Workers-specific module resolution
Bundles the Worker for deployment
Custom Build Options
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [ cloudflare ()] ,
build: {
target: "esnext" ,
minify: true ,
sourcemap: true ,
} ,
resolve: {
alias: {
"@" : "/src" ,
},
} ,
}) ;
Environment Variables
The plugin loads environment variables from .env files with CLOUDFLARE_ prefix:
# .env
CLOUDFLARE_ENV = staging
CLOUDFLARE_API_KEY = secret
Access in config:
// vite.config.ts
import { defineConfig , loadEnv } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig (({ mode }) => {
const env = loadEnv ( mode , process . cwd (), "CLOUDFLARE_" );
return {
plugins: [
cloudflare ({
config: {
vars: {
API_KEY: env . CLOUDFLARE_API_KEY ,
},
},
}),
],
};
} ) ;
TypeScript Support
The plugin provides full TypeScript support:
import type { PluginConfig , WorkerConfig } from "@cloudflare/vite-plugin-cloudflare" ;
const workerConfig : WorkerConfig = {
name: "my-worker" ,
main: "src/index.ts" ,
compatibility_date: "2024-01-01" ,
};
const pluginConfig : PluginConfig = {
config: workerConfig ,
persistState: true ,
};
Advanced Usage
Dynamic Configuration
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig (({ command , mode }) => {
const isDev = command === "serve" ;
const isProd = mode === "production" ;
return {
plugins: [
cloudflare ({
config ( workerConfig ) {
if ( isDev ) {
// Development overrides
workerConfig . vars = {
... workerConfig . vars ,
LOG_LEVEL: "debug" ,
};
}
if ( isProd ) {
// Production optimizations
return {
minify: true ,
};
}
},
}),
],
};
} ) ;
Conditional Bindings
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
config ( workerConfig ) {
// Add analytics only in production
if ( process . env . ENABLE_ANALYTICS === "true" ) {
workerConfig . analytics_engine_datasets = [
{ binding: "ANALYTICS" },
];
}
},
}),
] ,
}) ;
Custom Worker Entry
// vite.config.ts
import { defineConfig } from "vite" ;
import { cloudflare } from "@cloudflare/vite-plugin-cloudflare" ;
export default defineConfig ({
plugins: [
cloudflare ({
config: {
name: "custom-worker" ,
main: "./src/worker/index.ts" ,
},
}),
] ,
build: {
rollupOptions: {
input: "./src/worker/index.ts" ,
},
} ,
}) ;