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.
$ 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
—
- GitHub stars
- —
- Forks
- —
- Watchers
- —
- Open issues
- —
- Latest version
- —
- Last published
- —
- Versions released
- —
- Unpacked size
- —
- Dependencies
- —
- License
- MIT
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.
const stripe = new Stripe(process.env.STRIPE_KEY);
Missing
Referenced in code but defined in no .env file. This is what fails the build.
APP_NAME=Orders Dashboard
DATABASE_URL=postgres://…
Undocumented
In .env but missing from .env.example, so the next contributor won’t know it exists.
OLD_TOKEN=a81f…
PORT=3000
Unused
Defined but never referenced anywhere in code. Usually a leftover from a removed feature.
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.
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.
-
Run it
Point it at any project. No install needed.
npx envscan-cli --dir ./backend -
Check typos
Missing a variable you’re sure you defined? Get the closest match from
.env.example.npx envscan-cli --suggest -
Fix the example file
Adds empty placeholders to
.env.example. Your real.envis never touched.npx envscan-cli --fix -
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.
| Flag | What 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-unused | Hide unused variable warnings. |
--no-banner | Hide the startup banner. |
--fix | Add missing and undocumented variables to .env.example as placeholders. |
--json | Print a machine-readable JSON report instead of the CLI report. |
--no-secrets | Skip secret-leak detection for this run. |
-w, --watch | Re-run the audit on every source or .env change. |
--strict | Fail the build on undocumented and unused variables too, not just missing. |
--suggest | Suggest the closest .env.example name for each missing variable. |
-v, --version | Show the installed version. |
-h, --help | Show help and usage examples. |
No option matches that search.
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,
};
# .envscanignore
DEBUG
LEGACY_*
# pipe into dashboards or CI annotations
npx envscan-cli --json > report.json
# report keys
missing, undocumented, unused, secrets,
gitignoreProtectsEnv, strict, failReasons, meta
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.
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.