zero dependencies · node 18+ · MIT

Your .env.example is a contract.
Enforce it.

envdrift compares .env.example against live .env files across machines and directories — flags missing, extra, and secret-looking vars. CI gate mode included.

Install from npm View source
terminal
$ envdrift check

✗ drifted  .
  missing (in .env.example, not in .env):
    - FEATURE_FLAGS
    - LOG_LEVEL
  extra (in .env, not documented):
    + STRIPE_SECRET_KEY [secret-like]
  → 2 missing vars, 1 extra var, 1 secret-like var present

$ envdrift scan --dir ~/code --ci   # exit 1 on drift

Why envdrift

Deploys fail at 2am because prod never got a variable someone added on their laptop three months ago. Hand-diffing env files doesn't scale. Machines checking them does.

🔍

Missing vars

Every var documented in .env.example but absent from the live .env — the exact set that breaks deploys.

🧟

Extra vars

Undocumented variables living only on one machine. The zombie config nobody remembers adding.

🔐

Secret-looking flags

Heuristics flag undocumented vars shaped like keys, tokens, PEM blocks, and connection strings with embedded credentials. Names only — values are never printed.

🌲

Whole-machine scans

envdrift scan walks a directory tree and audits every project it finds — monorepos, server checkouts, your laptop.

🚦

CI gate mode

--ci exits non-zero on drift or incomplete pairs. Wire it into your pipeline in one line.

📦

Zero dependencies

One Node 18+ binary. Nothing installed alongside it, nothing to audit, nothing to break.

How it works

Thirty seconds, start to gate.

Install

npm i -g envdrift-cli

or run ad-hoc with npx envdrift-cli.

Check

envdrift check

Compare one project's env pair. JSON output with --format json.

Scan

envdrift scan --dir ~/code

Audit every project under a tree at once.

Gate

envdrift scan --ci

Non-zero exit on drift. Your pipeline decides what happens next.

Pricing

The CLI is free and stays free. Pro adds the team layer.