Skip to content

wrangler-resolve

wrangler-resolve is a thin CLI and programmatic wrapper around wrangler that integrates node-env-resolver into your Cloudflare Workers workflow.

It handles three things:

  • dev — serves resolved env via FIFO (secrets never touch disk on Unix) with hot reload on file changes
  • deploy — splits config into public vars (--var) and secrets (--secrets-file) automatically
  • types — generates a TypeScript Env interface from your schema
Terminal window
npm install node-env-resolver-cloudflare node-env-resolver
Terminal window
npx wrangler-resolve dev
npx wrangler-resolve deploy
npx wrangler-resolve versions upload
npx wrangler-resolve types

All unrecognized commands are passed through to wrangler unchanged.

  • dev refuses to start if .dev.vars exists — wrangler-resolve manages env injection itself. Remove .dev.vars and use .env files instead.
  • deploy manages --secrets-file automatically. Do not pass --secrets-file manually.
  • Set NER_CF_DEBUG=1 to enable debug logging.

By default the CLI uses processEnv() as the resolver source. To use custom resolvers, point NER_CF_CONFIG at a module that exports WranglerFacade options:

wrangler-resolve.config.ts
import { dotenv } from 'node-env-resolver/resolvers';
export default {
resolvers: [[dotenv('.env.local'), {}]],
watchPaths: ['.env.local', '.env.local.secrets'],
};
Terminal window
NER_CF_CONFIG=./wrangler-resolve.config.ts npx wrangler-resolve dev
import { WranglerFacade } from 'node-env-resolver-cloudflare';
import { dotenv } from 'node-env-resolver/resolvers';
const facade = new WranglerFacade({
resolvers: [[dotenv('.env'), { DATABASE_URL: postgres() }]],
});
await facade.dev(); // start dev server with hot reload
await facade.deploy(); // deploy with vars/secrets split
await facade.types(); // generate Env interface
OptionTypeDefaultDescription
resolvers[Resolver, SimpleEnvSchema][]requiredResolver + schema pairs
resolveOptionsPartial<ResolveOptions>Options forwarded to resolveAsync
watchPathsstring[]auto-detectedFiles to watch during dev
watchStrategy'auto', 'metadata', or 'fallback''auto'Auto-detect strategy for watch paths
watchDebouncenumber300Debounce ms between restarts
sensitivePrefixesstring[]common patternsKey prefixes that mark a value as secret
wranglerBinstring'wrangler'Custom wrangler binary name
debugbooleanfalseExtra logging
StrategyBehaviour
auto (default)Uses resolver metadata paths; falls back to .env, .env.local, .env.development, .env.development.local
metadataUses resolver-derived paths only, no fallback
fallbackIgnores resolver metadata, always uses the four common .env files

On Unix, createServingTempFile creates a named pipe (FIFO). Wrangler reads from it exactly once; the content is never written to a real file. On Windows a temp file is used instead.

Resolve values from Cloudflare Workers env bindings at runtime:

import { createCloudflareHandler } from 'node-env-resolver-cloudflare/handlers';
const handler = createCloudflareHandler({ env });
// resolves cf://MY_SECRET from the worker's env bindings

Cloudflare enforces a 5 KB limit per secret. When the serialized env blob exceeds that, wrangler-resolve automatically chunks it across multiple __NER_ENV_0, __NER_ENV_1, … secrets and reassembles them at runtime via reassembleEnvFromRecord.

import { reassembleEnvFromRecord } from 'node-env-resolver-cloudflare/chunking';
const env = reassembleEnvFromRecord(workerEnv);
Import pathExports
node-env-resolver-cloudflareWranglerFacade, createServingTempFile, chunking helpers, format helpers, createCloudflareHandler
node-env-resolver-cloudflare/handlerscreateCloudflareHandler, cfHandler
node-env-resolver-cloudflare/wranglerWranglerFacade
node-env-resolver-cloudflare/chunkingchunkString, addSerializedEnvToRecord, reassembleEnvFromRecord, CF_SECRET_MAX_BYTES
node-env-resolver-cloudflare/fifocreateServingTempFile