We've all been there. A new developer clones the repo, runs npm start, and gets a cryptic crash. Two hours later they realize .env.example was outdated. Or production goes down because DATABASE_URL wasn't set in CI.
Environment variables are one of the most error-prone parts of any project — yet most teams manage them with a shared .env.example file and hope.
I built env-drift-check to fix this.
What It Does
One CLI. No code changes to your app.
npx env-drift-check
✖ Missing keys:
- DATABASE_URL
- STRIPE_SECRET_KEY
❌ Validation failed: PORT must be a number
⚠ JWT_SECRET has low entropy — use a stronger secret
Fix everything interactively:
npx env-drift-check -i
Prompts for every missing variable, validates input in real time, masks secrets, and writes to .env. Onboarding goes from hours to under a minute.
Schema Validation — No Code Changes
Define rules in envwise.config.json:
{
"rules": {
"PORT": { "type": "number", "min": 1024, "max": 65535 },
"NODE_ENV": { "type": "enum", "values": ["development", "staging", "production"] },
"DEBUG_MODE": { "type": "boolean", "mustBeFalseIn": "production" },
"JWT_SECRET": { "type": "string", "checkSecretStrength": true },
"DATABASE_URL": { "type": "url", "required": true }
}
}
mustBeFalseIn: "production" ensures feature flags can never be true in production — even if someone forgets. Secret strength uses Shannon entropy math, not a keyword blocklist.
Other Commands
# Scan codebase for process.env usage vs .env.example
npx env-drift-check scan
# Diff two env files side by side
npx env-drift-check diff .env.staging .env.production
# Check if .env is in .gitignore / git history
npx env-drift-check audit
# Generate .env.example from your local .env
npx env-drift-check gen-example
CI/CD — Block Bad Deploys
- name: Validate environment
run: npx env-drift-check --system-env --strict
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
JWT_SECRET: ${{ secrets.JWT_SECRET }}
--strict exits with code 1 on any issue. Works with GitHub Actions, GitLab CI, CircleCI — any platform.
New: Kubernetes + Docker Compose
Split .env into a K8s ConfigMap + Secret automatically:
npx env-drift-check gen-configmap .env --name my-app --namespace production
Sensitive keys (password, secret, token, api_key) go into a Secret with base64-encoded values. Safe keys go into a ConfigMap. No more accidentally putting a database password in plain-text config.
Validate your docker-compose.yml against the schema:
npx env-drift-check validate-compose docker-compose.yml --strict
Service: web
✔ NODE_ENV — in schema
✖ LEGACY_CONFIG — not in schema
⚠ DATABASE_URL — required in schema but not set
vs. The Alternatives
| Feature | dotenv-safe | envalid | env-drift-check |
|---|---|---|---|
| Missing key detection | ✅ | ✅ | ✅ |
| Schema validation | ❌ | ✅ (in code) | ✅ (JSON config) |
| No code changes | ❌ | ❌ | ✅ |
| Interactive wizard | ❌ | ❌ | ✅ |
| Codebase scanner | ❌ | ❌ | ✅ |
| Git audit | ❌ | ❌ | ✅ |
| K8s / Docker Compose | ❌ | ❌ | ✅ |
Get Started
npm install --save-dev env-drift-check
npx env-drift-check init
npx env-drift-check -i
GitHub: shashi089/env-drift-check
npm: env-drift-check
If it saves you time, a ⭐ goes a long way.

Top comments (2)
Nice article - explains a common .env problem well and gives a simple fix. Useful, thanks for sharing!
Thanks! I appreciate you taking the time to read it. If you get a chance to try env-drift-check, I'd love to hear your feedback or feature suggestions.