DEV Community

Ghazanfar Uruj
Ghazanfar Uruj

Posted on

Stop shipping a .env.example that's already out of date

You add a new feature, it reads a new environment variable, you ship it. Three weeks later a teammate clones the repo, copies .env.example, runs the app — and it crashes on a KeyError for a variable nobody documented. Or the reverse: .env.example is full of variables that no code reads anymore, and new devs waste time setting them.

I wanted that drift caught automatically, so I built envcheck — a small, dependency-free CLI.

envcheck flagging an undocumented and an unused variable

How it works

envcheck never imports or runs your code. It parses each .py file with the standard-library ast module, collects every literal-key environment-variable access (os.getenv("X"), os.environ["X"], os.environ.get("X"), os.environ.setdefault("X", ...)), then diffs that against your example env file. Dynamic keys are ignored on purpose, so it never produces noisy false positives.

Using it

pip install envcheck-sync
envcheck .                      # auto-detects .env.example, .env.sample, ...
envcheck . --format json        # machine-readable for tooling
Enter fullscreen mode Exit fullscreen mode

It exits non-zero when it finds undocumented variables, so dropping envcheck . into CI or a pre-commit hook keeps your .env.example honest. It also reports possibly-unused variables as a warning (without failing) so you can prune them.

Why a static tool in the age of AI?

An AI assistant can spot a missing env var if you ask it, but envcheck is deterministic, runs headless in CI on every commit in milliseconds, reasons over your entire project at once, and never sends your code anywhere. It's the cheap, reliable gate — the same reason linters and type checkers keep thriving.

It's open source (MIT) and early — feedback and contributions welcome: https://github.com/gazzycodes/envcheck

Top comments (0)