dead-env
v1.5.0
Published
Find ghost and zombie environment variables in your codebase
Readme
dead-env
Hunt down ghost and zombie environment variables haunting your codebase.
What it does
Every project accumulates env var debt:
- 👻 Ghost variables — referenced in code (
process.env.STRIPE_KEY) but never defined in any.envfile. These will blow up silently at runtime. - 🧟 Zombie variables — defined in
.envbut never actually referenced anywhere in the code. Dead weight you're carrying around for no reason. - 🔀 Drift — the same variable is defined in multiple
.envfiles (.env,.env.production, etc.) with different values, which may indicate a misconfiguration or forgotten update.
Install
Once published to npm:
npm install -g dead-envOr run without installing:
npx dead-env .Or clone and run locally:
git clone https://github.com/yourname/dead-env
cd dead-env
pnpm install
pnpm start -- /path/to/your/projectUsage
Usage: dead-env [path] [options]
Arguments:
path Directory to scan (default: current directory)
Options:
--fix Append missing detected vars to the example file
--example-file Example file path for --fix (default: ".env.example")
--diff <files...> Compare two env files
--values Show actual values in --diff output
--validate Validate env vars used in code against discovered .env* files
--strict With --validate, exit with code 1 on unused env vars too
-e, --env <glob> Env file pattern (default: "**/.env*")
-x, --exclude Exclude node_modules, .git, dist (default: true)
--lang <langs> Languages to scan: js,ts,py,go
--json Output as JSON
--ci Emit GitHub Actions annotations in --validate mode
-V, --version Output the version number
-h, --help Show helpExamples
Scan the current directory:
dead-envScan a specific project:
dead-env ~/projects/myappOutput JSON (pipe-friendly):
dead-env --json | jq '.ghosts'Only look at .env and .env.production:
dead-env -e ".env{,.production}"Only scan Python and Go files:
dead-env --lang py,goValidate env usage against all discovered .env* files:
dead-env --validateFail CI on unused env vars too:
dead-env --validate --strictEmit GitHub Actions annotations on pull requests:
dead-env --validate --ciExample output
dead-env scan: ~/projects/myapp
────────────────────────────────
👻 Ghost Variables (used in code, not defined):
STRIPE_SECRET_KEY
└─ src/payments.ts:42, src/webhook.ts:8
NODE_ENV
└─ src/config.ts:3
🧟 Zombie Variables (defined in .env, never used):
OLD_API_ENDPOINT (.env)
🔀 Drift (same var, different across env files):
DATABASE_URL
└─ .env: "postgres://localhost/dev"
└─ .env.production: "postgres://prod/app"
────────────────────────────────
Summary: 2 ghost, 1 zombie, 1 drift issue(s)CI Integration
Add to your GitHub Actions workflow to catch env problems before they ship:
# .github/workflows/env-check.yml
name: Env Check
on:
push:
branches: [main]
pull_request:
jobs:
dead-env:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Run dead-env validation
run: npx dead-env --validate --ci .
# Fails on missing env vars and adds PR annotationsYou can also make it non-blocking (report only, don't fail the build):
- name: Run dead-env (advisory)
run: npx dead-env --validate --json . | tee env-report.json || true
- name: Upload env report
uses: actions/upload-artifact@v4
with:
name: env-report
path: env-report.jsonSupported languages
dead-env recognizes env var access patterns from:
- JavaScript / TypeScript —
process.env.VAR,process.env['VAR'] - Python —
os.environ.get('VAR'),os.environ['VAR'],os.getenv('VAR') - Go —
os.Getenv("VAR"),os.LookupEnv("VAR")
License
MIT
