Catch env drift before it catches you in production.
DotDrift scans your source code for every process.env.X reference, crosses it against your .env and .env.example files, and reports the exact drift: missing vars, leaked secrets, undocumented keys, and dead declarations, before you ship.
npx dotdrift scanEvery Node.js project eventually hits the same wall:
- A deploy breaks because a var exists locally but not in production
.env.examplehasn't been updated in 6 months- A
console.log(process.env)made it to prod - Nobody knows which vars in
.envare still actually used
Existing tools help a little. dotenv-linter validates .env syntax. detect-secrets catches committed secrets. But none of them cross-reference your source code against your env files to find the drift.
DotDrift is that missing tool.
# Zero-install (recommended for one-off scans)
npx dotdrift scan
# Global install
npm install -g dotdrift
# As a dev dependency (recommended for CI)
npm install --save-dev dotdriftRequirements: Node.js 18+
npx dotdrift@0.1.0 scanScans ./src by default, reads .env and .env.example if they exist.
npx dotdrift scan --dir src,lib --env .env,.env.production,.env.examplenpx dotdrift watchRe-scans automatically whenever source files or env files change.
npx dotdrift scan --format json{
"summary": { "errors": 2, "warnings": 2 },
"issues": [
{
"type": "leak",
"severity": "error",
"key": null,
"message": "process.env exposed to console.log()",
"file": "src/utils/debug.ts",
"line": 14
},
{
"type": "missing",
"severity": "error",
"key": "STRIPE_SECRET_KEY",
"message": "Used in code but not declared in any env file",
"file": "src/payments/charge.ts",
"line": 8
}
]
}npx dotdrift scan --fail-on missing,leakedCreate dotdrift.config.js at your project root:
// dotdrift.config.js
module.exports = {
dirs: ['src', 'lib'],
envFiles: ['.env', '.env.example', '.env.production'],
ignore: ['NODE_ENV', 'PORT'],
rules: {
'no-leaked-env': 'error',
'no-missing-env': 'error',
'no-undocumented-env': 'warn',
'no-unused-env': 'warn',
},
}DotDrift uses AST parsing (not regex), so it handles every access pattern:
| Pattern | Detected |
|---|---|
process.env.API_KEY |
✓ Direct access |
process.env['API_KEY'] |
✓ Computed access |
const { API_KEY } = process.env |
✓ Destructuring |
const { API_KEY: key } = process.env |
✓ Renamed destructuring |
console.log(process.env) |
✓ Full env leak |
JSON.stringify(process.env) |
✓ Full env leak |
Supports: .js .ts .jsx .tsx
- name: Check env drift
run: npx dotdrift scan --fail-on missing,leakedenv-check:
stage: lint
script: npx dotdrift scan --fail-on missing,leakednpx husky add .husky/pre-commit "npx dotdrift scan --fail-on missing,leaked"| Rule | Default | Description |
|---|---|---|
no-leaked-env |
error |
console.log(process.env) and full-env exposures |
no-missing-env |
error |
Used in code, not in any env file |
no-undocumented-env |
warn |
Used in code, missing from .env.example |
no-unused-env |
warn |
In .env but never referenced in source |
| DotDrift | dotenv-linter | detect-secrets | |
|---|---|---|---|
| Reads source code AST | ✓ | ✗ | ✗ |
| Missing var detection | ✓ | ✗ | ✗ |
| Unused var detection | ✓ | ✗ | ✗ |
| Env leak detection | ✓ | ✗ | partial |
| Watch mode | ✓ | ✗ | ✗ |
| Zero config | ✓ | ✓ | ✗ |
| CI exit code | ✓ | ✓ | ✓ |
v0.1 (current): AST scanner, drift detection, leak detection, watch mode, JSON output
v0.2: SARIF output for GitHub annotations, extended secret leak rules
v0.3: VS Code extension, auto-fix stubs, dotdrift init
v1.0: Docker/Kubernetes support, ESLint plugin
git clone https://github.com/diegosantdev/dotdrift
cd dotdrift && npm install && npm testPRs welcome. Open an issue first for significant changes.
MIT

