Cloudflare Workers
Varlock provides a robust solution for managing environment variables in Cloudflare Workers, offering validation, type safety, and security features that go beyond Cloudflare’s built-in environment variable and secrets handling.
Both approaches below use varlock-wrangler — a thin wrapper around wrangler that automatically resolves and uploads your env vars as Cloudflare secrets and vars during deployment, and injects them into miniflare during local dev.
Two approaches
Section titled “Two approaches”- Using
varlock-wrangler- A thin wrapper forwranglerthat injects env vars correctly, along with a one-line init import in your worker - With the Vite plugin - If you’re already using the Cloudflare Workers Vite plugin, you can add the varlock Cloudflare Vite plugin to automatically inject env vars and init code
Approach 1: Using varlock-wrangler
Section titled “Approach 1: Using varlock-wrangler”Replace your wrangler commands with varlock-wrangler and initialize varlock in your worker code with a single import. It’s a thin wrapper that wires up your env vars correctly, and passes everything else through unchanged.
-
Install packages
Terminal window npm install @varlock/cloudflare-integration varlockTerminal window pnpm add @varlock/cloudflare-integration varlockTerminal window bun add @varlock/cloudflare-integration varlockTerminal window yarn add @varlock/cloudflare-integration varlockTerminal window vlt install @varlock/cloudflare-integration varlock -
Run
varlock initto set up your.env.schemafileThis will guide you through setting up your
.env.schemafile, based on your existing.envfile(s). Make sure to review it carefully.Terminal window npm exec -- varlock initTerminal window pnpm exec -- varlock initTerminal window bun exec varlock initTerminal window vlx -- varlock initTerminal window yarn exec -- varlock init -
Add the varlock init import to your worker entry point
This initializes varlock’s
ENVproxy and applies console redaction and response leak detection (unless disabled):src/index.ts import '@varlock/cloudflare-integration/init';import { ENV } from 'varlock/env';export default {async fetch(request, env, ctx) {// both work:console.log(ENV.MY_VAR); // varlock (recommended)console.log(env.MY_VAR); // native Cloudflarereturn new Response('Hello!');},}; -
Update your package.json scripts to use
varlock-wranglerpackage.json {"scripts": {"dev": "varlock-wrangler dev","deploy": "varlock-wrangler deploy","types": "varlock-wrangler types",}}
How it works
Section titled “How it works”- In dev:
varlock-wrangler devresolves your env and injects it intowranglerusing--env-filewith a named pipe (unix/mac) or temp file (windows). It also watches your.envfiles and automatically restarts wrangler when they change - somethingwrangler devdoesn’t do. - In production:
varlock-wrangler deploy(andvarlock-wrangler versions upload) attaches non-sensitive values as Cloudflare vars (via--var) and sensitive values as Cloudflare secrets via--secrets-file. The worker reads them at runtime viaimport { env } from 'cloudflare:workers'.
Approach 2: With the Vite plugin
Section titled “Approach 2: With the Vite plugin”If you’re already using the Cloudflare Workers Vite plugin, varlockCloudflareVitePlugin is a thin wrapper that adds env var and varlock init code injection — no additional init import needed, and both ENV.MY_VAR and native env.MY_VAR work in dev and production.
-
Install packages
Terminal window npm install @varlock/cloudflare-integration @cloudflare/vite-plugin varlockTerminal window pnpm add @varlock/cloudflare-integration @cloudflare/vite-plugin varlockTerminal window bun add @varlock/cloudflare-integration @cloudflare/vite-plugin varlockTerminal window yarn add @varlock/cloudflare-integration @cloudflare/vite-plugin varlockTerminal window vlt install @varlock/cloudflare-integration @cloudflare/vite-plugin varlock -
Run
varlock initto set up your.env.schemafileTerminal window npm exec -- varlock initTerminal window pnpm exec -- varlock initTerminal window bun exec varlock initTerminal window vlx -- varlock initTerminal window yarn exec -- varlock init -
Update your Vite config
Replace the
cloudflare()plugin withvarlockCloudflareVitePlugin()— it is a thin wrapper of the Cloudflare vite plugin and passes through all config:vite.config.ts import { defineConfig } from 'vite';import { cloudflare } from '@cloudflare/vite-plugin';import { varlockCloudflareVitePlugin } from '@varlock/cloudflare-integration';export default defineConfig({plugins: [cloudflare(),varlockCloudflareVitePlugin(),// other plugins ...],});Any options you were passing to
cloudflare()can be passed directly tovarlockCloudflareVitePlugin():varlockCloudflareVitePlugin({persistState: true,inspectorPort: 9229,}) -
Update your deploy script to use
varlock-wranglerpackage.json {"scripts": {"dev": "vite dev","build": "vite build","deploy": "npm run build && varlock-wrangler deploy"}}
How it works
Section titled “How it works”- In dev: Resolved vars are automatically injected into miniflare’s bindings.
- In production: Non-sensitive values are statically replaced at build time by vite.
varlock-wrangler deploysets non-sensitive values as Cloudflare vars and sensitive values as secrets.
Upgrading from @varlock/vite-integration
Section titled “Upgrading from @varlock/vite-integration”If you were previously using varlockVitePlugin() from @varlock/vite-integration with Cloudflare Workers:
- Install
@varlock/cloudflare-integration(you can remove@varlock/vite-integration— it’s included) - In
vite.config.ts, replace bothvarlockVitePlugin()andcloudflare()withvarlockCloudflareVitePlugin() - Replace
wrangler deploywithvarlock-wrangler deployin your deploy script
import { varlockVitePlugin } from '@varlock/vite-integration';import { cloudflare } from '@cloudflare/vite-plugin';import { varlockCloudflareVitePlugin } from '@varlock/cloudflare-integration';
export default defineConfig({ plugins: [ varlockVitePlugin(), cloudflare(), varlockCloudflareVitePlugin(), ],});Your secrets will no longer be bundled into the JS artifact — they’ll be stored in Cloudflare’s secret management instead.
varlock-wrangler CLI
Section titled “varlock-wrangler CLI”varlock-wrangler is a thin wrapper around wrangler. It enhances the following commands:
varlock-wrangler dev
Section titled “varlock-wrangler dev”Wraps wrangler dev with automatic env injection:
- Resolves your environment variables
- Injects them into miniflare
- Watches your
.envfiles and restarts wrangler automatically when they change
varlock-wrangler deploy / versions upload
Section titled “varlock-wrangler deploy / versions upload”- Resolves your environment variables using your
.env.schemaand.envfiles - Uploads non-sensitive values as Cloudflare vars (
--varflags) - Uploads sensitive values as Cloudflare secrets (
--secrets-file) - Includes a
__VARLOCK_ENVsecret containing the full resolved env graph for the varlock runtime
varlock-wrangler types
Section titled “varlock-wrangler types”Generates Cloudflare Worker types (the Env interface) including all varlock-managed environment variables. This ensures your env.MY_VAR access is properly typed alongside other Cloudflare bindings (KV, D1, etc.).
varlock-wrangler typesOther commands
Section titled “Other commands”All other wrangler commands (e.g., tail, secret list) are passed through to wrangler unchanged. You can use varlock-wrangler all the time, or just continue to use wrangler except for the commands listed above.
Log redaction and leak prevention
Section titled “Log redaction and leak prevention”Both integration approaches automatically enable log redaction (sensitive values are masked in console output) and response leak detection (responses are scanned for accidentally exposed secrets). These are enabled by default and can be disabled in your .env.schema using root decorators:
# @redactLogs=false# @preventLeaks=falseFor more details, see the root decorators reference.
Managing Multiple Environments
Section titled “Managing Multiple Environments”Varlock can load multiple environment-specific .env files (e.g., .env.development, .env.preview, .env.production) by using the @currentEnv root decorator.
If you are using Cloudflare’s CI, you can use the current branch name (WORKERS_CI_BRANCH) to determine the environment:
# @currentEnv=$APP_ENV# ---WORKERS_CI_BRANCH=# @type=enum(development, preview, production, test)APP_ENV=remap($WORKERS_CI_BRANCH, "main", production, regex(.*), preview, undefined, development)For more information, see the environments guide.