DEV Community

benjamin
benjamin

Posted on

I built a 1-file CLI to catch .env drift before it causes production bugs

Almost every developer has fought .env issues. They're silent, annoying, and they only show up after you deploy or after someone clones the repo.

Here's the exact failure I hit one too many times:

  1. I add STRIPE_KEY to my local .env.
  2. I ship code that reads process.env.STRIPE_KEY.
  3. I forget to add STRIPE_KEY to the committed .env.example.
  4. A teammate clones, runs the app, and it crashes on a missing variable.

The reverse is just as common: .env.example promises a key you never actually set locally — a silent misconfig waiting to bite.

The two files are supposed to declare the same set of keys. They drift apart constantly. So I built a small guardrail.

dotdrift

Zero dependencies, one command:

npx dotdrift
Enter fullscreen mode Exit fullscreen mode
x drift detected between .env and .env.example

  Missing in .env.example (add these so teammates know they're needed):
    + STRIPE_KEY

  Tip: run "dotdrift sync" to update .env.example automatically.
Enter fullscreen mode Exit fullscreen mode

It exits non-zero on drift, so it drops straight into CI:

- run: npx dotdrift --strict   # --strict also flags empty values
Enter fullscreen mode Exit fullscreen mode

The part I actually wanted: sync

Detecting drift is half the problem. The annoying half is fixing the template by hand. So sync regenerates .env.example from your real .env:

npx dotdrift sync
Enter fullscreen mode Exit fullscreen mode
  • values are stripped (KEY=),
  • your comments and blank-line grouping are preserved,
  • curated placeholders already in the template survive (a hand-written PORT=3000 stays),
  • it's idempotent — run it twice, nothing changes.

So updating the template is now one command instead of a manual chore.

Make it permanent

npx dotdrift hook
Enter fullscreen mode Exit fullscreen mode

Installs a .git/hooks/pre-commit that blocks commits when things drift. A one-time tool becomes a continuous safety net.

Monorepo

npx dotdrift -r
Enter fullscreen mode Exit fullscreen mode

Scans every subdirectory that has an .env/.env.example pair (skips node_modules, dist, etc.) and reports per service.

Notes

  • Zero dependencies — Node stdlib only, ~250 lines.
  • It only ever compares key names (and, with --strict, whether a value is empty). It never prints or transmits your secret values.
  • Understands KEY=value, export KEY=value, single/double quotes, KEY= (empty), # comments, and inline comments on unquoted values.
  • MIT licensed.

Repo: https://github.com/jjdoor/dotdrift
npm: npx dotdrift

If you hit a parsing edge case or the sync output isn't what you'd expect, open an issue — that's exactly the feedback I'm after.

Top comments (0)