check

Validate environment variables against the schema with CI-friendly exit codes.

Edit on GitHub

arkenv check validates the active environment against your schema without starting the app. Run it in CI, a local script, or a pre-commit hook when the failure should happen before boot.

The bare command uses the environment already on the process. Add --env-file to load a dotenv file first (later files win). Add --schema when the module is not env.ts or src/env.ts.

npx arkenv check
npx arkenv check --env-file .env.production
npx arkenv check --schema ./src/env.ts --env-file .env --env-file .env.local

Global flags (--quiet, --json, --agent, --help) apply here too.

Usage

Terminal
arkenv check [options]

When the environment satisfies the schema, check prints a success line and exits with code 0:

Terminal
✔ No issues found — your environment matches the schema

When validation fails, check outputs the formatted issues and exits with code 4. That band means "the command ran, and the environment does not match the schema" — not an internal crash (1) or a missing schema (2):

Terminal
Errors found while validating environment variables
  DATABASE_URL must be a URL string (was [REDACTED])
  PORT must be a number (was a string)

Before validating, check loads the schema under capture mode (imports the module with a hollow {} stub). Keep the schema module declarative.

Options

These flags are specific to check.

--schema <path> / -s

Explicit path to the schema module. Overrides convention discovery (env.ts or src/env.ts). A JavaScript schema is not auto-discovered; pass --schema (for example --schema ./env.js). Split-layout leftovers such as env/server.ts are not auto-discovered. For a two-module recipe, pass --schema at the client (or other loadable) module — not a server file that imports server-only, which the CLI cannot evaluate in plain Node.

npx arkenv check --schema ./src/config/env.ts

When you omit --schema, check looks for a schema at flat convention paths only. Put custom locations in your scripts with --schema (for example "check": "arkenv check --schema config/env.ts"). The CLI does not read a package.json "arkenv" field for discovery.

--env-file <file>

Load a .env file before validating. This flag is repeatable; multiple files are loaded in sequence with later files taking precedence over earlier ones.

npx arkenv check --env-file .env --env-file .env.local

Values from --env-file are merged over process.env. Missing files fail fast with a non-zero exit code. Parsing is literal plain dotenv syntax (no variable expansion).

--verify-example [file]

Verify that every environment variable declared in the schema is present in .env.example (or a custom example file path) without mutating files on disk.

npx arkenv check --verify-example
npx arkenv check --verify-example .env.example.production

When all schema keys exist in the example file, check exits with 0. When keys are missing, check outputs the missing keys and exits with code 4. This mode specifically verifies example file parity against declared schema keys and does not validate live environment variables.

--json / -j

Write a settlement envelope to stdout. Success is ok: true with exitCode: 0:

{
  "ok": true,
  "commandId": "check",
  "result": { "schema": { "path": "env.ts" } },
  "exitCode": 0,
  "diagnostics": [],
  "nextActions": []
}

Validation findings are still ok: true — the command completed — with exitCode: 4 and diagnostics / nextActions for each key. Missing schema or a missing --env-file is ok: false with a dotted CLI.* code and exit 2.

{
  "ok": true,
  "commandId": "check",
  "result": { "schema": { "path": "env.ts" } },
  "exitCode": 4,
  "diagnostics": [
    {
      "code": "ENV.MISSING_VARIABLE",
      "severity": "error",
      "summary": "DATABASE_URL is required",
      "nextActions": [
        {
          "kind": "edit-file",
          "label": "Set DATABASE_URL in .env",
          "where": { "path": ".env" }
        }
      ]
    }
  ],
  "nextActions": [
    {
      "kind": "edit-file",
      "label": "Set DATABASE_URL in .env",
      "where": { "path": ".env" }
    }
  ]
}

--quiet / -q

Suppress normal console output. JSON envelopes still go to stdout when --json is set. Exit codes stay the same: 0 success, 2 could not run, 4 findings.

CI/CD integration

Add arkenv check to CI so a missing or invalid variable fails the job before the build or deploy. --verify-example checks that .env.example still lists every schema key, so a new key without an example entry fails the job:

.github/workflows/ci.yml
name: CI

on: [push, pull_request]

jobs:
  validate-example:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - name: Verify .env.example matches schema
        run: pnpm exec arkenv check --verify-example

  validate-env:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - name: Validate environment
        env:
          DATABASE_URL: ${{ secrets.DATABASE_URL }}
          PORT: "3000"
        run: pnpm exec arkenv check

Next steps