v2.0.3 on npm, MIT licensed

Catch broken environment variables before your deploy does.

envscan-cli reads your code and your .env files, then shows exactly where they’ve drifted apart — plus any secrets that shouldn’t be sitting there.

npx envscan-cli

No install, no config, no account. Works in any Node.js project.

~/my-app
$ npx envscan-cli

✖ MISSING (2) used in code but not in any .env file
  ❯ JWT_SECRET      src/auth.js:12
  ❯ STRIPE_KEY      src/payments.js:8

⚠ UNDOCUMENTED (1) in .env, not in .env.example
  ❯ APP_NAME

○ UNUSED (1) defined in .env, never used
  ❯ OLD_TOKEN

2 missing · 1 undocumented · 1 unused
Scanned 3 files in 0.1s

Live from npm and GitHub

Loading the latest numbers…

Total npm downloads

Last 7 days
Last 30 days
Best day
GitHub stars
Forks
Watchers
Open issues
Latest version
Last published
Versions released
Unpacked size
Dependencies
License
MIT
Star on GitHub Full download history

npm updates download counts once a day, so today isn’t included yet.

Environment variables rot quietly

A teammate adds process.env.STRIPE_KEY in a new module and forgets .env.example. Nobody notices until a deploy fails. Old keys pile up long after the code that used them is gone. A real secret ends up in a .env that was never gitignored. envscan-cli finds all of it in one pass.

What it catches

Five checks, run together every time. Here’s what each one looks like in a real project.

src/payments.js
const stripe = new Stripe(process.env.STRIPE_KEY);

Missing

Referenced in code but defined in no .env file. This is what fails the build.

.env
APP_NAME=Orders Dashboard
DATABASE_URL=postgres://…

Undocumented

In .env but missing from .env.example, so the next contributor won’t know it exists.

.env
OLD_TOKEN=a81f…
PORT=3000

Unused

Defined but never referenced anywhere in code. Usually a leftover from a removed feature.

.env.production
AWS_ACCESS_KEY_ID=AKIA••••••••••••
GITHUB_TOKEN=ghp_••••••••••••

Potential secret leaks

Known credential formats — AWS, Stripe live keys, GitHub, Slack, Google API keys, PEM blocks, JWTs — plus high-entropy values on names like *SECRET* or *TOKEN*. Only the name and reason are printed, never the value.

.gitignore
node_modules/
dist/
# .env is not listed

Gitignore hygiene

Warns when your .env isn’t actually covered by .gitignore, before it gets committed.

From first run to CI gate

Most projects go through these four steps once, then leave envscan-cli running in CI.

  1. Run it

    Point it at any project. No install needed.

    npx envscan-cli --dir ./backend
  2. Check typos

    Missing a variable you’re sure you defined? Get the closest match from .env.example.

    npx envscan-cli --suggest
  3. Fix the example file

    Adds empty placeholders to .env.example. Your real .env is never touched.

    npx envscan-cli --fix
  4. Gate your deploys

    Generates a ready-to-commit GitHub Actions workflow.

    npx envscan-cli init-ci

What --suggest prints

✖ MISSING (1)
❯ DATABASE_URL
    src/db.js:4
    💡 Did you mean DB_URL instead of DATABASE_URL?

Every option

CLI flags always override the config file.

FlagWhat it does
-d, --dir <path>Directory to scan. Defaults to the current working directory.
-e, --example <path>Custom path to your .env.example file.
-c, --config <path>Use a specific config file instead of auto-detection.
--ignore-unusedHide unused variable warnings.
--no-bannerHide the startup banner.
--fixAdd missing and undocumented variables to .env.example as placeholders.
--jsonPrint a machine-readable JSON report instead of the CLI report.
--no-secretsSkip secret-leak detection for this run.
-w, --watchRe-run the audit on every source or .env change.
--strictFail the build on undocumented and unused variables too, not just missing.
--suggestSuggest the closest .env.example name for each missing variable.
-v, --versionShow the installed version.
-h, --helpShow help and usage examples.

Configure once, or not at all

Drop an envscan-cli.config.js or .envscan-clirc.json in your project root and it’s picked up automatically. Prefer a plain list? Use .envscanignore, gitignore-style, with trailing wildcards like LEGACY_*.

Both ignore lists are merged, so use whichever suits you.

// envscan-cli.config.js
export default {
  // Names/patterns excluded from every check
  ignore: ['LEGACY_*', 'DEBUG'],
  exampleFile: '.env.example',
  ignoreUnused: false,
  secretDetection: true,
};

A pre-deploy gate that takes one line

envscan-cli exits with code 1 whenever a variable is missing, so the job fails before a broken build reaches production.

Default
Fails only on missing variables. Everything else is reported as advice.
--strict
Also fails on undocumented and unused variables.
--strict --ignore-unused
Strict on missing and undocumented, relaxed on unused.
.github/workflows/envscan-cli.yml
name: envscan-cli

on:
  pull_request:
  push:
    branches: [main]

jobs:
  audit-env:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - name: Audit environment variables
        run: npx envscan-cli --dir . --ignore-unused

Every release is verifiable

Releases are published only from a GitHub Release, using npm Trusted Publishing (OIDC) — no stored npm tokens. Each version carries a provenance attestation tying it to the exact workflow run and commit that built it. Check the Provenance tab on any version’s npm page.

Questions

Does envscan-cli ever print my secret values?

No. Only the variable name and the reason it was flagged are printed. The value itself never appears in the CLI report or the JSON output.

Will --fix change my real .env file?

No. --fix only appends empty placeholders (VAR_NAME=) to .env.example, which should never hold real values anyway.

Which .env files are scanned for secrets?

.env, .env.local, .env.development and .env.production. .env.example is never scanned for secrets.

How reliable are the --suggest typo hints?

They’re edit-distance based. They catch most renames and typos, but can occasionally suggest a name that isn’t actually related, so treat them as a hint.

When does it fail a CI build?

By default, only when variables are missing (exit code 1). Add --strict to fail on undocumented or unused variables too.

Can I turn off secret detection?

Yes. Pass --no-secrets for a single run, or set secretDetection: false in your config file.

Audit your project in the next ten seconds.

npx envscan-cli

Found a bug or have an idea? Open an issue on GitHub.