Reserved variables
varlock reserves a couple of environment variable namespaces for its own use. Knowing them helps you avoid surprises and understand how varlock passes state between processes.
| Prefix | Example | Who sets it |
|---|---|---|
VARLOCK_* (no underscore) | VARLOCK_ENV | varlock (computed); see Builtin variables |
_VARLOCK_* (single underscore) | _VARLOCK_ENV_KEY | you, to configure varlock’s behavior |
__VARLOCK_* (double underscore) | __VARLOCK_ENV | varlock internals, injected automatically; never set these yourself |
Configuration variables (_VARLOCK_*)
Section titled “Configuration variables (_VARLOCK_*)”Set these in your shell, CI, or deploy environment to configure varlock’s behavior.
_VARLOCK_ENV_KEY
Section titled “_VARLOCK_ENV_KEY”Encryption key used to decrypt the injected env blob at runtime. Typically set in deploy environments. See Encrypted deployments.
_VARLOCK_ALLOW_PLAINTEXT_FROZEN_ENV
Section titled “_VARLOCK_ALLOW_PLAINTEXT_FROZEN_ENV”Set to 1 in the build environment to let a Next.js build freeze the env into its output without encrypting it. Without it, a frozen build fails when _VARLOCK_ENV_KEY is not set.
_VARLOCK_CACHE_KEY
Section titled “_VARLOCK_CACHE_KEY”Encryption key for the on-disk resolved-value cache. When set (e.g. as a CI secret), it enables the disk cache in environments without OS keychain access. See Caching.
_VARLOCK_REDACT_STDOUT
Section titled “_VARLOCK_REDACT_STDOUT”Overrides stdout/stderr redaction, both for varlock run output and for in-process redaction in varlock/auto-load and framework integrations (see @redact):
true/1: force redaction on. Forvarlock runthis only applies to piped/redirected output and errors if attached to an interactive terminal. In-process, it also enables redaction when the schema does not set@redact={stdout=true}, and applies even to a terminal.false/0: disable redaction entirely
For varlock run, the --redact-stdout / --no-redact-stdout flags take precedence over this env var. Useful when you can’t easily change the command being run, for example in a wrapper script or CI config.
_VARLOCK_FILTER
Section titled “_VARLOCK_FILTER”Fallback for the --filter flag on varlock load / varlock run. An explicit --filter flag takes precedence over this env var. Useful when you can’t easily pass a CLI flag, for example a wrapper script, CI config, or a build-time integration that invokes varlock’s loading APIs directly.
_VARLOCK_FILTER="#billing" varlock load --format json_VARLOCK_DYNAMIC_BUILD_ACCESS_MODE
Section titled “_VARLOCK_DYNAMIC_BUILD_ACCESS_MODE”Set to warn to downgrade the build/prerender-time guard on public+dynamic config access from an error to a one-time warning per key. Useful while migrating an existing app that still reads dynamic public values in prerendered pages.
_VARLOCK_THROW_ON_LOAD_ERROR
Section titled “_VARLOCK_THROW_ON_LOAD_ERROR”When set (1 / true), varlock/auto-load throws the error on a load failure instead of exiting, so an already-initialized error tracker (e.g. Sentry) can capture it via its uncaughtException handler. Setting a globalThis._varlockOnLoadError hook enables the same throw behavior. See Reporting load failures.
_VARLOCK_ALLOW_EMPTY_CONFIG
Section titled “_VARLOCK_ALLOW_EMPTY_CONFIG”When set (1 / true), allows loading an empty config: no .env files found, or files that define no items. varlock load and varlock run succeed with an empty config instead of erroring, and varlock/auto-load and the framework integrations skip their empty-config warning. Use it for deploys that intentionally ship no .env files. Parse errors still fail, and other commands (for example varlock proxy) still require config items.
_VARLOCK_USE_INJECTED_ENV
Section titled “_VARLOCK_USE_INJECTED_ENV”Controls whether varlock/auto-load and varlock run reuse an already-injected __VARLOCK_ENV blob (e.g. from a parent varlock run) instead of re-resolving:
- unset (default): reuse the blob only when it was resolved in the same directory the consumer would resolve in, and nothing relevant has changed since
1/true: always trust the blob, skipping the directory check. Use this to hand a blob into an environment with no.envfiles: a sandbox, or a deploy carrying the payload fromvarlock freeze --out -. auto-load hydrates a Node app from it, andvarlock runinjects its values into any child command. Missing or unusable blobs are hard errors, as is a blob created from a failed resolution.0/false: always re-resolve
Values are matched case-insensitively; any other value is ignored (same as unset). varlock run flags that change what a resolution produces (--path, --filter, --clear-cache, --skip-cache, --include-internal) disable reuse, and are rejected when combined with 1.
See Reusing an injected env blob.
_VARLOCK_USE_FROZEN_ENV
Section titled “_VARLOCK_USE_FROZEN_ENV”Boots varlock/auto-load, varlock run, and varlock load from a frozen env file produced by varlock freeze instead of resolving:
- unset (default): never read a frozen env file, even when one is present. Resolve normally
1/true: use.varlock-frozen-envin the working directory. A missing file is a hard error, so a pipeline that failed to produce it cannot silently fall back to resolving at boot- any other value: the path to the frozen env file, relative to the working directory unless absolute
A frozen env file that is asked for but unusable (missing, unreadable, encrypted with no _VARLOCK_ENV_KEY, or encrypted with a different key) is always an error, never a fallback to fresh resolution. 1/true is the only recognized toggle (0/false are accepted as unset), so a value like off is read as a path and fails as a missing file.
--frozen [path] on run and load is the flag form. varlock load --frozen shows the frozen values with any boot-time values for @dynamic=boot keys applied, without reading the schema.
This takes precedence over an ambient __VARLOCK_ENV blob, and is independent of _VARLOCK_USE_INJECTED_ENV: setting that to 0 does not disable frozen env files. varlock run flags that change what a resolution produces (--path, --filter, --clear-cache, --skip-cache, --include-internal) are rejected when a frozen env file is in play.
Internal variables (__VARLOCK_*)
Section titled “Internal variables (__VARLOCK_*)”These are injected automatically so that varlock state survives across process boundaries. You should never set them yourself. They’re documented here only so you recognize them if you see them in a process environment.
__VARLOCK_ENV
Section titled “__VARLOCK_ENV”The serialized env graph (resolved config values plus metadata) injected by varlock run and build-time integrations, so the runtime can load your config without re-invoking the CLI. @internal items are excluded from this blob by default everywhere it’s built, including framework integrations.
__VARLOCK_RUN
Section titled “__VARLOCK_RUN”A marker set so a child process can detect that it is running under varlock run. Scripts that re-exec themselves under varlock run should check this first so they do not recurse. On macOS with Homebrew Python, do not pass sys.executable into that re-exec: see Auto-invoking varlock run from Python.
__VARLOCK_REDACTED_STREAMS
Section titled “__VARLOCK_REDACTED_STREAMS”Set by varlock run and varlock proxy run on the child process as <parent pid>:<streams>, listing which of its streams (stdout, stderr) the parent is already piping through redaction. In-process stdout redaction in that direct child skips those streams so output isn’t redacted twice, unless the stream has been redirected to a file. Grandchildren (e.g. node app.js | tee log inside a shell) redact their own output, since their stdout may not lead to the redacted pipe.
__VARLOCK_CLI_CHILD
Section titled “__VARLOCK_CLI_CHILD”Set on the varlock CLI process that varlock/auto-load and the framework integrations spawn to resolve your env. If varlock/auto-load is preloaded into that CLI process as well (for example via bun’s bunfig.toml preload, where bun also stands in for node), it sees this marker and skips resolving instead of spawning another CLI, which would otherwise recurse forever. The CLI removes the marker from its own environment on startup, so processes it spawns (varlock run children, exec() resolvers, plugins) never inherit it.
__VARLOCK_EXECUTION_PHASE
Section titled “__VARLOCK_EXECUTION_PHASE”Set to build by build-time integrations (e.g. the Vite plugin during vite build) so the runtime can detect app code executing during build/prerender and apply the public+dynamic access guard.