---
title: CLI Commands
description: Reference documentation for Varlock CLI commands
---

import ExecCommandWidget from "@/components/ExecCommandWidget.astro";

Varlock provides a command-line interface for managing environment variables and secrets. This reference documents all available CLI commands.

See [installation](/getting-started/installation) for instructions on how to install Varlock. You can also enable [shell completion](/guides/shell-completion/) for tab completion of commands and flags.


### Running commands in JS projects

If you have installed varlock as a `package.json` dependency, rather than a standalone binary, the best way to invoke the CLI is via your package manager:

<ExecCommandWidget command="varlock ..." showBinary={false} />

Also note that within package.json scripts, you can use it directly:
```json title="package.json"
{
  "scripts": {
    "start": "varlock run -- node app.js"
  }
}
```

### `package.json` configuration

You can configure varlock's default behavior by adding a `varlock` key to your `package.json`:

```json title="package.json"
{
  "varlock": {
    "loadPath": "./envs/"
  }
}
```

| Option | Description |
|--------|-------------|
| `loadPath` | Path (or array of paths) to a directory or specific `.env` file to use as the default entry point. Defaults to the current working directory if not set. Use a **directory path** (with trailing `/`) to automatically load all relevant files (`.env.schema`, `.env`, `.env.local`, etc.); a file path only loads that file and its explicit imports. When an array is provided, all paths are loaded and combined, with later entries taking higher precedence. Can be overridden by the `--path` CLI flag. Varlock looks for this config in the `package.json` in the current working directory only. |


:::note[Plugins]
While plugins cannot add additional CLI commands, they can extend varlock with additional [resolver functions](/reference/functions/), [data types](/reference/data-types/), and [decorators](/reference/item-decorators/). See the [Plugins guide](/guides/plugins/) for more information.
:::

## Common options

Several commands share these flags. They behave identically wherever they appear, except where a command's own section calls out a deviation.

- `--path` / `-p` `<path>`: Path to a specific `.env` file or directory to use as the entry point (overrides `varlock.loadPath` in `package.json`). Can be specified multiple times to load from multiple paths, where later paths take higher precedence. _(For [`scan`](#scan) and [`audit`](#audit) this is the **schema** entry point used to resolve sensitive values; `audit` accepts a single path only.)_
- `--env <env>`: Resolve in the context of a specific environment (e.g., `--env production`). Overridden by `@currentEnv` if it is set in your `.env.schema`.
- `--clear-cache`: Clear the active cache store before resolving values, then re-resolve all values (when combined with `--skip-cache`, the cache is cleared first, then reads and writes are skipped for the run).
- `--skip-cache`: Skip cache entirely for this invocation (no reads or writes). This overrides `@cache=disk`/`@cache=memory`.

## Commands reference

<div class="reference-docs">

<div>
### `varlock init` ||init||
Starts an interactive onboarding process to help you get started. Will help create your `.env.schema` and install varlock as a dependency if necessary.

```bash
varlock init [options]
```

**Options:**
- `--agent`: Run non-interactively for agent/automation workflows. Skips confirmation prompts and uses deterministic defaults for schema generation.

**Examples:**
```bash
# Interactive setup wizard
varlock init

# Non-interactive setup for AI agents
varlock init --agent
```

:::tip
Install the Varlock agent skill with `npx skills add dmno-dev/varlock` or `gh skill install dmno-dev/varlock varlock`. See the [AI Tools guide](/guides/ai-tools/#install-the-varlock-skill) for more.
:::

</div>

<div>
### `varlock load` ||load||

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.

```bash
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`](/reference/item-decorators/#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](#common-options): `--env`, `--path` / `-p`, `--clear-cache`, `--skip-cache`

**Examples:**
```bash
# 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
```

**Exit codes:**
- `0` when all config is valid
- non-zero when validation fails (missing required values, failed coercion, or resolver errors)

**Output formats (for scripts & agents):**
- `--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`](/reference/item-decorators/#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.

:::caution
Setting `@currentEnv` in your `.env.schema` will override the `--env` flag.
:::

</div>

<div>
### `varlock run` ||run||

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.

```bash
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`](/reference/item-decorators/#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](#common-options): `--path` / `-p`, `--clear-cache`, `--skip-cache`

**Examples:**
```bash
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
```

:::note[Shell expansion of env vars in commands]
Because of the way that shell expansion works, you may need to use use `sh -c` to properly expand environment variables in your command _after_ varlock has injected them.
```bash
varlock run -- echo $MY_VAR # ❌ will not work
varlock run -- sh -c 'echo $MY_VAR' # ✅ will work
```
:::

:::note[Interactive tools and TTY detection]
`varlock run` automatically detects where each output stream is going:

- **Interactive terminal (TTY)**: output passes straight through, preserving raw TTY behavior. Interactive tools like `psql` and `claude` work with no flags needed. A human at the terminal already has access to the secrets, so redaction adds little there.
- **Piped or redirected output** (CI logs, files, `| tee`, etc.): output is piped through a redaction filter, since that's where leaked secrets would persist.

Detection is per stream. For example `varlock run -- node app.js | tee log.txt` redacts stdout (piped) while stderr (still attached to your terminal) passes through.

To override the auto-detection:
```bash
# force-disable redaction even when output is piped/redirected
varlock run --no-redact-stdout -- node app.js | tee log.txt

# force redaction of piped output even when @redactLogs=false is set
varlock run --redact-stdout -- node app.js > log.txt
```

Redacting a TTY-attached stream is not possible without piping it (which would break interactive tools), so `--redact-stdout` errors if output is attached to an interactive terminal rather than silently degrading the experience.

The same override can be set via the [`_VARLOCK_REDACT_STDOUT`](/reference/reserved-variables/#_varlock_redact_stdout) environment variable (`true`/`1` to force on, `false`/`0` to force off), which is handy when you can't easily change the command being run, for example in a wrapper script or CI config. The CLI flag always takes precedence over the env var.
:::

:::note[Preventing sensitive value exposure via env inspection]
By default, `varlock run` injects a `__VARLOCK_ENV` variable containing the full serialized config graph (including resolved sensitive values) into the child process environment. This is used by framework integrations to obtain sensitivity metadata without re-invoking the CLI.

For long-lived processes, interactive shells, or any workflow where subprocesses may inspect their environment (e.g., `env`, `printenv`, or an LLM-driven agent), use `--inject vars` to inject only the individual vars and omit this blob:
```bash
varlock run --inject vars -- bash
varlock run --inject vars -- claude
```

Note: When the `__VARLOCK_ENV` blob is omitted, framework integrations that rely on it will need to fall back to re-invoking the CLI. `__VARLOCK_RUN=1` is always set regardless of this flag.
:::

:::note[Signals and exit codes]
`varlock run` stays resident while your command runs, but it gets out of the way of process termination:

- Terminating signals (`SIGTERM`, `SIGINT`, `SIGHUP`, `SIGQUIT`) are **forwarded** to the child so it can run its own shutdown handlers, rather than being killed abruptly. When no terminal is attached (containers, CI, background/agent runs), the child runs in its own process group and the signal is forwarded to the whole group, so grandchildren are terminated too.
- The child's exit status is **propagated faithfully**: a normal exit code passes through unchanged, and a child terminated by signal N exits with `128+N` (e.g. `143` for `SIGTERM`), matching shell conventions.

This makes `varlock run` safe to use as a container `ENTRYPOINT` (including PID 1), so `docker stop` / pod termination reaches your app gracefully instead of waiting out the grace period and being `SIGKILL`ed.

By default varlock forwards and then waits indefinitely for the child. It does **not** impose its own kill deadline, leaving that decision to the orchestrator or operator (a forwarded signal isn't always terminal, since many programs use `SIGHUP` to reload). If you want varlock to escalate to `SIGKILL` when the child hasn't exited within a grace period, set the `_VARLOCK_FORCE_KILL_TIMEOUT_MS` environment variable to a number of milliseconds.
:::

</div>

<div>
### `varlock printenv` ||printenv||

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.

```bash
varlock printenv <VAR_NAME> [options]
```

**Positional arguments:**
- `<VAR_NAME>`: The variable to print. Required; printenv errors if omitted.

**Options:**
- [Common options](#common-options): `--path` / `-p`, `--clear-cache`, `--skip-cache`

**Examples:**
```bash
# 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)'
```

:::note[Why not use `varlock run -- echo $MY_VAR`?]
Shell expansion happens *before* varlock runs, so `$MY_VAR` is substituted by the shell with whatever value it already has (likely empty). `varlock printenv` avoids this by printing the value directly to stdout, letting you capture it with `$(...)` *after* varlock has resolved it.

```bash
varlock run -- echo $MY_VAR         # ❌ shell expands $MY_VAR before varlock runs
varlock printenv MY_VAR             # ✅ varlock resolves and prints the value
sh -c 'echo $(varlock printenv MY_VAR)'  # ✅ embed in a larger command
```
:::

</div>

<div>
### `varlock explain` ||explain||

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.

```bash
varlock explain <VAR_NAME> [options]
```

**Positional arguments:**
- `<VAR_NAME>`: The config item to explain. Required; explain errors if omitted.

**Options:**
- [Common options](#common-options): `--env`, `--path` / `-p`

**Examples:**
```bash
# Explain how a value is resolved
varlock explain DATABASE_URL

# Explain in the context of a specific environment
varlock explain --env production API_KEY
```

</div>

<div>
### `varlock scan` ||scan||

Scans your project files for sensitive config values that should not appear in plaintext. Loads your varlock config, resolves all `@sensitive` values, then checks files for any occurrences of those values.

This is especially useful as a **pre-commit git hook** to prevent accidentally committing secrets into version control, and for **scanning build output** to ensure no secrets leaked into files that will be published or deployed.

**Exit codes:** `0` when no plaintext secrets are found; `1` when a leaked value is detected. This makes it usable directly as a pre-commit hook or CI gate.

```bash
varlock scan [paths...] [options]
```

**Positional arguments:**
- `[paths...]`: Optional list of file paths, directories, or glob patterns to scan. When provided, only these targets are scanned: git filtering (`--staged`, `--include-ignored`) is bypassed and build-output directories that are normally skipped (such as `dist`, `.next`, `build`) are included.

**Options:**
- `--staged`:           Only scan staged git files (ignored when explicit paths are provided)
- `--include-ignored`:  Include git-ignored files in the scan (ignored when explicit paths are provided)
- `--install-hook`:     Set up `varlock scan` as a git pre-commit hook
- [Common options](#common-options): `--path` / `-p` (here it sets the **schema** entry point used to resolve sensitive values)

**Examples:**
```bash
# Scan all non-gitignored files in the current directory
varlock scan

# Only scan staged git files
varlock scan --staged

# Scan all files, including gitignored ones
varlock scan --include-ignored

# Scan a specific build output directory (e.g. to check for leaked secrets before publishing)
varlock scan ./dist

# Scan multiple directories
varlock scan ./dist ./public

# Scan files matching a glob pattern
varlock scan './dist/**/*.js'

# Use a specific .env file as the schema entry point
varlock scan --path .env.prod

# Use multiple schema entry points
varlock scan -p ./envs -p ./overrides

# Set up as a git pre-commit hook
varlock scan --install-hook
```

:::tip[Git pre-commit hook]
The easiest way to set up scanning as a pre-commit hook is to run:
```bash
varlock scan --install-hook
```
This will detect if you are using a hook manager (like husky or lefthook) and provide the appropriate setup instructions. Otherwise, it will create a `.git/hooks/pre-commit` hook for you automatically.

If varlock is installed as a project dependency, the hook command will be automatically prefixed with your package manager (e.g., `npx varlock scan`).

You can also set it up manually. See the [Secrets guide](/guides/secrets/#scanning-for-leaked-secrets) for more details.
:::

</div>

<div>
### `varlock encrypt` ||encrypt||

Encrypts sensitive values using device-local encryption. Encrypted values are stored in `.env` files using the `varlock()` resolver function and are automatically decrypted at load time.

On macOS, encryption is hardware-backed via the Secure Enclave (with Touch ID / biometric authentication). On Windows, keys are TPM-sealed when a TPM is available (Windows Hello gates interactive decrypts). On Linux, TPM2 and/or Secret Service is used. A pure-JavaScript file-based fallback is available on all platforms.

See the [local encryption guide](/guides/local-encryption/) for platform details. On Windows, existing DPAPI keys are automatically upgraded to TPM sealing on the next decrypt.

```bash
varlock encrypt [options]
```

**Options:**
- `--file`:    Path to a `.env` file; encrypts all sensitive plaintext values in-place

**Examples:**
```bash
# Interactive mode: encrypt a single value (prompts with hidden input)
varlock encrypt

# Pipe a value via stdin (keeps secrets out of shell history)
printf '%s' "$SECRET" | varlock encrypt
varlock encrypt < secret.txt

# Encrypt all sensitive plaintext values in a .env file
varlock encrypt --file .env.local
```

In single-value mode, you'll either be prompted to enter a value (hidden input) or the value will be read from stdin when piped. The encrypted output is printed for you to copy into your `.env.local` file:
```
SOME_SENSITIVE_KEY=varlock("local:<encrypted>")
```

:::tip
Piping via stdin avoids exposing secrets in your shell history. Prefer `printf '%s'` over `echo` to avoid a trailing newline (varlock strips a single trailing newline either way).
:::

In file mode, varlock loads the env graph, identifies `@sensitive` items with plaintext values, and lets you select which to encrypt in-place.

:::tip
Use `varlock encrypt --file .env.local` after adding new secrets to quickly encrypt them all at once.
:::

:::note[Alternative: prompt mode]
Instead of encrypting values ahead of time, you can use `varlock(prompt)` as a placeholder in your `.env` files. On first load, varlock will prompt you to enter the secret and automatically replace the placeholder with the encrypted value. See the [`varlock()` function reference](/reference/functions/#varlock) for details.
:::

</div>

<div>
### `varlock reveal` ||reveal||

Securely view or copy the value of a `@sensitive` environment variable. The value is displayed in an alternate terminal screen buffer so it doesn't persist in your scrollback history.

🔒 Usually sensitive values are redacted, so this is needed to actually view the value without exposing it in plaintext on disk or in your terminal history.

```bash
varlock reveal [VAR_NAME] [options]
```

**Options:**
- `--copy`:        Copy the value to clipboard instead of displaying (auto-clears after 10s)
- [Common options](#common-options): `--path` / `-p`, `--env`

**Examples:**
```bash
# Interactive picker to browse and reveal sensitive values
varlock reveal

# Reveal a specific variable
varlock reveal MY_SECRET

# Copy a value to clipboard (auto-clears after 10s)
varlock reveal MY_SECRET --copy
```

:::note
Non-sensitive values are not shown by `varlock reveal`. Use [`varlock printenv`](#printenv) for non-sensitive values, or to inject a sensitive value into a command.
:::

:::note[Clipboard support on Linux]
`varlock reveal --copy` uses your system clipboard command (`xclip` or `xsel`) on Linux. Install one of them if copy mode is unavailable.
:::

</div>

<div>
### `varlock lock` ||lock||

Locks the encryption daemon, requiring biometric authentication (e.g., Touch ID) for the next decrypt operation. This invalidates the current biometric session cache.

```bash
varlock lock
```

This command only has an effect when using a biometric-enabled encryption backend (macOS Secure Enclave, Windows Hello, or Linux with polkit/PAM biometric setup). On other backends, it will display a message and exit.

:::tip
Use `varlock lock` when stepping away from your machine to ensure the next person to decrypt a secret must authenticate biometrically.
:::

</div>

<div>
### `varlock audit` ||audit||

Scans your source code for environment variable references and compares them against keys defined in your schema.

This command reports two drift categories:
- **Missing in schema**: key is used in code but not declared in schema
- **Unused in schema**: key is declared in schema but not referenced in code

Pure execution-environment plumbing, meaning variables that reflect *where/how* the process runs (e.g. `PATH`, `HOME`, `SHELL`, `NODE_OPTIONS`, `npm_*`), is read from `process.env` in normal code but is never part of your schema, so it is **not** reported as missing. Semantically meaningful variables your app or CI may depend on (e.g. `NODE_ENV`, `CI`, GitHub Actions vars) are still reported, so you can decide whether to declare them or suppress them with [`@auditIgnore`](/reference/item-decorators/#auditignore).

Exit codes:
- `0` when schema and code are in sync
- `1` when drift is detected

```bash
varlock audit [paths...] [options]
```

**Positional arguments:**
- `[paths...]`: Optional list of directories to scan. When provided, only these directories are scanned instead of the auto-detected scan root.

**Options:**
- [Common options](#common-options): `--path` / `-p` (here it sets the **schema** entry point, single path only)
- `--ignore` / `-i`: Directory to exclude from code scanning (can be specified multiple times)

**Examples:**
```bash
# Audit current project
varlock audit

# Audit using a specific .env file as schema entry point
varlock audit --path .env.prod

# Audit using a directory as schema entry point
varlock audit --path ./config

# Only scan specific directories
varlock audit ./src ./lib

# Exclude directories from scanning
varlock audit --ignore vendor

# Exclude multiple directories
varlock audit -i vendor -i generated
```

:::note
When `--path` points to a directory, code scanning is scoped to that directory tree. When it points to a file, scanning is scoped to that file's parent directory.
:::

:::note[Monorepos]
Code scanning does not descend into nested projects. Any subdirectory that contains its own `package.json` or `.env.schema` is treated as a separate package and skipped. This keeps a parent package's audit from picking up env var references that belong to child packages, and works even in a fresh monorepo where the child packages haven't run `varlock init` yet. Run `varlock audit` inside each package to audit it against its own schema.
:::

:::tip[Suppressing false positives]
- Use [`@auditIgnore`](/reference/item-decorators/#auditignore) on individual schema items that are only consumed by external tools and won't appear in your application code.
- Use [`@auditIgnorePaths()`](/reference/root-decorators/#auditignorepaths) to exclude directories (e.g., vendored code, generated files) from the code scan.
:::

</div>

<div>
### `varlock cache` ||cache||

Manage the encrypted **disk cache** used by [`cache()`](/reference/functions/#cache) and plugin authors when cache mode is set to `disk`. When run in a TTY, opens an interactive browser; otherwise prints a status summary.

```bash
varlock cache [status|clear] [options]
```

**Sub-commands:**
- `status`: print a non-interactive cache status summary (location, file size, entry counts by group)
- `clear`: remove cache entries. Requires `--yes` for non-interactive use.

**Options:**
- `--plugin <name>`: When clearing, only remove entries for a specific plugin
- `--yes` / `-y`: Skip confirmation prompts (required when clearing without a TTY)

**Examples:**
```bash
# Interactive cache browser (or status summary in CI)
varlock cache

# Print a non-interactive status summary
varlock cache status

# Clear all cache entries (prompts to confirm)
varlock cache clear

# Clear all cache entries without confirming (e.g. CI)
varlock cache clear --yes

# Clear cache for a specific plugin only
varlock cache clear --plugin 1password --yes
```

:::note
When global cache mode is `memory` (or disabled), this command does not show per-process in-memory entries.
:::

See the [Caching guide](/guides/caching/) for cache mode strategy and troubleshooting.

</div>

<div>
### `varlock codegen` ||codegen||

Runs the [code-generation decorators](/reference/root-decorators/#code-generation) in your schema: typed env accessors like `@generateTsTypes` (type declarations) and `@generatePythonEnv` (a loadable module), plus any generators contributed by plugins. Uses only your schema definitions, so output is deterministic regardless of which environment is active. Keys (and decorators) that come only from value files like `.env` or `.env.local` are ignored. Only items declared in your `.env.schema` (or imported into it) are included. When run directly, the command reports any keys found only in a plain `.env` so you can move them into your schema if they belong there.

Add a per-language decorator for each output file you want: `@generateTsTypes`, `@generatePythonEnv`, `@generateRustEnv`, `@generateGoEnv`, or `@generatePhpEnv`. Each generates its own file.

This command is particularly useful when you have set `auto=false` on a generator decorator to disable automatic generation during `varlock load` or `varlock run`.

:::note
`varlock typegen` is a deprecated alias for `varlock codegen`. It still works but prints a warning.
:::

```bash
varlock codegen [options]
```

**Options:**
- [Common options](#common-options): `--path` / `-p`

**Examples:**
```bash
# Generate using the default schema
varlock codegen

# Generate from a specific .env file
varlock codegen --path .env.prod

# Generate from multiple directories
varlock codegen -p ./envs -p ./overrides
```

</div>

<div>
### `varlock telemetry` ||telemetry||

Opts in/out of anonymous usage analytics. This command creates/updates a configuration file at `$XDG_CONFIG_HOME/varlock/config.json` (defaults to `~/.config/varlock/config.json`) saving your preference.

```bash
varlock telemetry disable
varlock telemetry enable
```

:::note
You can also temporarily opt out by setting the `VARLOCK_TELEMETRY_DISABLED` environment variable. See the [Telemetry guide](/guides/telemetry/) for more information about our analytics and privacy practices.
:::
</div>

<div>
### `varlock generate-key` ||generate-key||

Generates a random 256-bit encryption key for use with `_VARLOCK_ENV_KEY`. This key is used to encrypt the resolved env blob that gets baked into your build output on certain frameworks/platforms.

```bash
varlock generate-key
```

See the [Next.js](/integrations/nextjs/#encrypting-the-env-blob) and [Vite](/integrations/vite/#encrypting-the-env-blob) integration docs for setup instructions.

</div>

<div>
### `varlock install-plugin` ||install-plugin||

Pre-downloads a plugin from npm into the local varlock plugin cache so it is available without an interactive confirmation prompt. This is mainly for the **standalone binary** in CI or other non-interactive environments. When varlock runs as a package.json dependency, plugins resolve through your normal node_modules instead.

The plugin must be specified with an exact version (`name@version`).

```bash
varlock install-plugin <name@version>
```

**Positional arguments:**
- `<name@version>`: The plugin to install, with an exact version (e.g. `my-plugin@1.2.3`).

**Examples:**
```bash
# Install a plugin at an exact version
varlock install-plugin my-plugin@1.2.3

# Scoped package
varlock install-plugin @my-scope/my-plugin@2.0.0
```

</div>

<div>
### `varlock help` ||help||

Displays general help information, alias for `varlock --help`

```bash
varlock help
```

For help about specific commands, use:

```bash
varlock subcommand --help
```

</div>
</div>
