It works on your machine. You deploy. The first real request hits the endpoint and the app 500s — because STRIPE_WEBHOOK_SECRET was never set in production. Somebody added the key to .env.example three PRs ago, you pulled it, ran the code locally with your own .env, and never noticed the mismatch. Every deploy checklist has a line that says "did you update the env vars?" and nobody ever reads it.
dotenv-diff turns that checklist line into a command. Diff .env against .env.example and catch missing keys before deploy, not after:
curl -O https://raw.githubusercontent.com/hahahahahahahahah6/dotenv-diff/main/dotenv_diff.py
chmod +x dotenv_diff.py
./dotenv_diff.py
ERRORS:
[missing] STRIPE_WEBHOOK_SECRET
WARNINGS:
[extra] LEGACY_MAILGUN_KEY
[placeholder] DATABASE_URL (value: 'postgres://changeme@localhost/db')
1 error(s), 2 warning(s)
Four finding types: missing (in the example, absent from .env — an ERROR), plus extra, empty, and placeholder warnings (changeme, xxx, <...>, todo… — values that were clearly never filled in). Exit code 0 if clean, 1 on any ERROR; --strict also fails on warnings, which is the mode you want in CI. --json emits machine-readable findings, and either side can read from stdin with -.
This is not a secret manager. It doesn't encrypt, sync, or rotate anything — it's a ~200-line gate that answers one question: does the env this code runs with match the env the code was written against? Pair it with direnv: dotenv-diff validates, direnv loads.
Stdlib only, Python 3.9+. 9/9 tests pass. MIT licensed.
Repo: https://github.com/hahahahahahahahah6/dotenv-diff
What's the worst "forgot the env var" outage you've caused — or witnessed?
Top comments (0)