---
title: @envlock/cli
description: The envlock command — check, example, diff, inspect, and init.
url: https://pr-1-7abef52380a8.thally.app/envlock-cli
---

# @envlock/cli

The envlock command — check, example, diff, inspect, and init.

`@envlock/cli` provides the `envlock` command for validating environment
variables, generating `.env.example`, detecting drift, and inspecting contracts.

```bash
npm install -D @envlock/cli
npx envlock --help
```

## Config file discovery

The CLI looks for `envlock.config.mjs` or `envlock.config.js` in the current
directory, or accepts an explicit `--schema <path>`. The file must
`export default defineEnv({...})` (a named `schema` export is also accepted).

Run `npx envlock init` to generate a starter config.

## Commands

### `envlock check`

Validates `process.env`, or a dotenv file when `--env-file` is given.

```bash
# Validate the current shell environment
npx envlock check

# Validate a dotenv file in strict mode (report undeclared keys)
npx envlock check --env-file .env --strict

# Layer a dotenv file over process.env
npx envlock check --env-file .env --merge-process-env

# JSON output
npx envlock check --json
```

| Flag | Description |
| --- | --- |
| `--schema <path>` | Explicit path to the config file. |
| `--env-file <path>` | Validate a dotenv file instead of `process.env`. |
| `--merge-process-env` | Layer the dotenv file over `process.env`. |
| `--strict` | Report undeclared keys. Applies to files only (ignored with a note for `process.env`). |
| `--json` | Output as JSON. |

### `envlock example`

Renders `.env.example` to stdout, writes it to a file, or checks for drift.

```bash
# Print to stdout
npx envlock example

# Write to file
npx envlock example --out .env.example

# CI: exit 1 if the committed file is stale
npx envlock example --check
```

| Flag | Description |
| --- | --- |
| `--schema <path>` | Explicit config file path. |
| `--out <path>` | Write the output to a file. |
| `--check` | Compare the rendered text against `--out` / `.env.example` and exit 1 on drift. |

### `envlock diff`

Lists missing, unknown, and invalid keys in a dotenv file. Always validates
in strict mode.

```bash
npx envlock diff                      # defaults to .env
npx envlock diff --env-file .env.local
npx envlock diff --json
```

| Flag | Description |
| --- | --- |
| `--schema <path>` | Explicit config file path. |
| `--env-file <path>` | Dotenv file to diff (default: `.env`). |
| `--json` | Output as JSON. |

### `envlock inspect`

Prints the contract as a human-readable table, or as `describeSchema()` JSON.

```bash
npx envlock inspect
npx envlock inspect --json
```

### `envlock init`

Writes a starter `envlock.config.mjs` in the current directory. Refuses to
overwrite an existing config file (exits 1).

```bash
npx envlock init
```

## Exit codes

| Code | Meaning |
| --- | --- |
| `0` | Validation passed / no drift. |
| `1` | Validation failed, `.env.example` drift, or `init` found an existing config. |
| `2` | Usage error: unknown command or flag, missing flag value, stray argument. |
| `3` | Config error: no config found, import failed, module did not export a schema, or the env file could not be read. |

## Programmatic use

`@envlock/cli` exports `runCli` so other tools can embed the CLI without
spawning a subprocess:

```ts
import { runCli, EXIT_CODES, type CliIo } from "@envlock/cli";

const io: CliIo = {
  stdout: (text) => process.stdout.write(text),
  stderr: (text) => process.stderr.write(text),
  cwd: process.cwd(),
  env: process.env,
};

const code = await runCli(["check", "--env-file", ".env"], io);
process.exitCode = code;
```

### Exported API

| Export | Description |
| --- | --- |
| `runCli(argv, io)` | Main entry point. Returns the exit code. |
| `parseArgs(argv, specs)` | Hand-rolled argv parser. |
| `loadSchema(cwd, explicitPath?)` | Resolves and imports the schema. |
| `resolveConfigPath(cwd, explicit?)` | Finds the config file path. |
| `importSchema(path)` | Imports and validates a module's schema export. |
| `EXIT_CODES` | `{ ok: 0, failure: 1, usage: 2, config: 3 }` |
| `CONFIG_CANDIDATES` | `["envlock.config.mjs", "envlock.config.js"]` |
| `STARTER_CONFIG` | The template written by `envlock init`. |