DEV Community

TECHDEV
TECHDEV

Posted on Originally published at github.com

Your .env file is lying to you. I built a tiny tool to catch it.

Your .env file is lying to you. I built a tiny tool to catch it.

Every new AI tool wants another API key. So my .env file kept growing β€” and one day I realized I no longer trusted it.

A teammate cloned the repo, followed .env.example, and the app crashed. A key that was in .env had never been added to the example. An old key that nobody used anymore was still there. And somewhere in the middle sat STRIPE_KEY=changeme, which had been there long enough that nobody noticed.

Formatters and linters check whether your .env file looks right. None of them told me whether my env setup was actually correct. So I built a small tool that does exactly that: env-doctor.

What it checks

One stdlib-only Python CLI. No dependencies, no network, no telemetry.

python -m env_doctor check --env .env --example .env.example
Enter fullscreen mode Exit fullscreen mode
Check What it finds
Drift Keys in .env.example missing in .env, and vice versa
Duplicates Same key defined twice
Placeholders Empty values, changeme, your-api-key, TODO, xxx, ...
Risky secrets Known prefixes (ghp_, sk-, AKIA, ...) or long high-entropy values
Unused vars Keys not referenced in scanned code (--scan .)
Invalid lines Lines without =, invalid key names

Exit code 0 means no errors, 1 means errors found. Warnings never fail the run on their own, so you can use it in CI without false failures from heuristics.

What it looks like

$ python -m env_doctor check --env examples/drift/.env --example examples/drift/.env.example
[ERROR] duplicate-key: Duplicate key 'DATABASE_URL' (line 3)
[ERROR] missing-in-env: 'NEW_API_URL' is in .env.example but missing in .env
[WARN ] placeholder-value: 'STRIPE_KEY' still looks like a placeholder value
[WARN ] missing-in-example: 'OLD_FLAG' is in .env but missing in .env.example
Summary: 2 error(s), 2 warning(s), 3 key(s).
Enter fullscreen mode Exit fullscreen mode

That drift/ example ships in the repo, broken on purpose, so you can see the output immediately.

Try it in 3 steps

# 1. Clone
git clone https://github.com/techdevfun/env-doctor.git
cd env-doctor

# 2. No dependencies to install (Python 3.9+ stdlib only).
#    Optional: install the `env-doctor` command
pip install -e .

# 3. Run it
python -m env_doctor check --env .env --example .env.example
Enter fullscreen mode Exit fullscreen mode

A few more ways to use it:

# Clean setup β€” should pass
python -m env_doctor check --env examples/basic/.env --example examples/basic/.env.example

# JSON output for CI / scripts
python -m env_doctor check --env examples/drift/.env --example examples/drift/.env.example --format json

# Also flag vars not referenced in code
python -m env_doctor check --env .env --example .env.example --scan .
Enter fullscreen mode Exit fullscreen mode

And in CI, it's one step:

- name: Audit .env drift
  run: python -m env_doctor check --env .env --example .env.example --format text
Enter fullscreen mode Exit fullscreen mode

The repo runs the same check in .github/workflows/ci.yml on Python 3.9, 3.11, and 3.12.

What's next

On the roadmap: --fix to auto-add missing keys to .env.example as empty placeholders, --strict to turn selected warnings into errors, support for .env.local / .env.production layering checks, and SARIF output for GitHub code scanning.

If you try it and it misses a case your project hits, open an issue β€” that's the feedback that shapes what gets built next.

Repo: https://github.com/techdevfun/env-doctor

Top comments (0)