Skip to content

Load and run

Loads and validates environment variables according to your .env files, and prints the results. Default prints a nicely formatted, colorized summary of the results, but can also print out machine-readable formats.

Useful for debugging locally, and in CI to print out a summary of env vars.

Terminal window
varlock load [options]

Options:

  • --format: Format of output [pretty|json|env|shell|json-full]
  • --agent: Agent-safe mode: defaults to JSON output and redacts sensitive values. Not compatible with --format env or --format shell.
  • --compact: Compact output (json-full: no indentation, env/shell: skip undefined values)
  • --show-all: Shows all items, not just failing ones, when validation is failing
  • --include-internal: Include @internal items in --format json-full output. Excluded by default (json-full is commonly consumed programmatically, e.g. by framework integrations, not just for local human inspection) - pass this for local debugging of a secret-zero credential.
  • Common options: --env, --path / -p, --clear-cache, --skip-cache, --filter

Examples:

Terminal window
# Load and validate environment variables
varlock load
# Load and validate for a specific environment (when not using @currentEnv in .env.schema)
varlock load --env production
# Output validation results in JSON format
varlock load --format json
# Output full serialized graph (including errors/configErrors fields)
varlock load --format json-full
# Compact output
varlock load --format json-full --compact
# Output as shell export statements (useful for direnv / eval)
eval "$(varlock load --format shell)"
# When validation is failing, will show all items, rather than just failing ones
varlock load --show-all
# Load from a specific .env file
varlock load --path .env.prod
# Load from a specific directory
varlock load --path ./config/
# Load from multiple directories (later paths take higher precedence)
varlock load -p ./envs -p ./overrides
# Agent-safe JSON output with sensitive values redacted
varlock load --agent
# Only show STRIPE_* keys, excluding one
varlock load --filter="STRIPE_*,!STRIPE_DEBUG_KEY"
# Only show items marked @sensitive
varlock load --filter="@sensitive"
# Only show items tagged with @tag(billing)
varlock load --filter="#billing"

Exit codes:

  • 0 when all config is valid
  • non-zero when validation fails (missing required values, failed coercion, or resolver errors)
  • --format json: a flat { "KEY": value } map of resolved values on stdout
  • --agent: the same flat map, but @sensitive values are redacted (e.g. "su▒▒▒▒▒"), so it is safe to print in logs or agent transcripts. Implies JSON output; not compatible with --format env/shell. Combine with --agent --format json-full to get the redacted full graph.
  • --format json-full: the full serialized graph: top-level basePath, sources, config (per-item metadata including resolved value, validation state, and sensitivity), settings. Use this when you need per-item validation/error detail rather than just values. ⚠️ This includes raw resolved secret values, so add --agent (--agent --format json-full) to redact them before logging or feeding to an agent. @internal items are excluded unless you pass --include-internal.
  • --format env / --format shell: dotenv lines / shell export statements with raw values. Never pipe these somewhere that gets logged when secrets are involved.

When emitting machine-readable output, add --summary-stderr (or --summary-file) to get a human-readable, redacted summary on stderr while keeping clean JSON on stdout. This is handy for agents and CI.

Executes a command in a child process, injecting your resolved and validated environment variables from your .env files. This is useful when a code-level integration is not possible.

Terminal window
varlock run -- <command>

Exit codes: varlock run exits with the child command’s exit code, so it is transparent in scripts and CI. If varlock itself fails before the command starts (e.g. invalid config or a failed resolver), it exits non-zero without running the command.

Options:

  • --redact-stdout / --no-redact-stdout: Override automatic stdout/stderr redaction. --redact-stdout forces redaction of piped/redirected output (e.g., to override @redactLogs=false) and errors if output is attached to an interactive terminal, where redaction is not possible without breaking TTY behavior. --no-redact-stdout disables redaction entirely.
  • --inject <mode> / -i: Control what gets injected into the child process environment: all (default: individual vars plus the __VARLOCK_ENV serialized config graph blob), vars (individual vars only, no blob), or blob (only the __VARLOCK_ENV blob, no individual vars)
  • --include-internal: Pass @internal items through to the child process. By default they are stripped from the child env, even if set in the ambient environment, so a secret-zero token never reaches your app. Use this for a nested varlock run whose own resolution needs the internal value.
  • Common options: --path / -p, --clear-cache, --skip-cache, --filter

Examples:

Terminal window
varlock run -- node app.js # Run a Node.js application
varlock run -- python script.py # Run a Python script
# Use a specific .env file as entry point
varlock run --path .env.prod -- node app.js
# Use a specific directory as entry point
varlock run --path ./config/ -- node app.js
# Use multiple directories as entry points
varlock run -p ./envs -p ./overrides -- node app.js
# Only inject STRIPE_* keys, excluding one (also strips them from the __VARLOCK_ENV blob)
varlock run --filter="STRIPE_*,!STRIPE_DEBUG_KEY" -- node app.js

Resolves and prints the value of a single environment variable to stdout. Only the requested item and its transitive dependencies are resolved, making this faster than loading the full graph.

This is useful within larger shell commands where you need to embed a single resolved env var value.

Exit codes: 0 when the value resolves; non-zero when no variable name is given, the variable is not in the schema, or it fails to resolve.

Terminal window
varlock printenv <VAR_NAME> [options]

Positional arguments:

  • <VAR_NAME>: The variable to print. Required; printenv errors if omitted.

Options:

Examples:

Terminal window
# Print the resolved value of MY_VAR
varlock printenv MY_VAR
# Use a specific .env file as entry point
varlock printenv --path .env.prod MY_VAR
# Use multiple directories as entry points
varlock printenv -p ./envs -p ./overrides MY_VAR
# Embed in a shell command using subshell expansion
sh -c 'some-tool --token $(varlock printenv MY_TOKEN)'

Shows detailed information about how a single config item is resolved: all of its definitions, sources, overrides, and the final resolved value. This is the go-to command for debugging why a value is what it is (and an agent-friendly way to inspect resolution without dumping every value).

Sensitive values are redacted in the output.

Exit codes: 0 when the item is found and explained; non-zero when no key is given or the key is not in the schema.

Terminal window
varlock explain <VAR_NAME> [options]

Positional arguments:

  • <VAR_NAME>: The config item to explain. Required; explain errors if omitted.

Options:

Examples:

Terminal window
# Explain how a value is resolved
varlock explain DATABASE_URL
# Explain in the context of a specific environment
varlock explain --env production API_KEY