███████╗███╗ ██╗██╗ ██╗██████╗ ██████╗ ██████╗████████╗ ██████╗ ██████╗
██╔════╝████╗ ██║██║ ██║██╔══██╗██╔═══██╗██╔════╝╚══██╔══╝██╔═══██╗██╔══██╗
█████╗ ██╔██╗ ██║██║ ██║██║ ██║██║ ██║██║ ██║ ██║ ██║██████╔╝
██╔══╝ ██║╚██╗██║╚██╗ ██╔╝██║ ██║██║ ██║██║ ██║ ██║ ██║██╔══██╗
███████╗██║ ╚████║ ╚████╔╝ ██████╔╝╚██████╔╝╚██████╗ ██║ ╚██████╔╝██║ ██║
╚══════╝╚═╝ ╚═══╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝
───────────────🩺 Environment Integrity, Drift & Code Auditor 🩺───────────────
End Silent Production Outages Caused by Missing Environment Variables.
A zero-dependency CLI & GitHub Action that validates .env contracts, automatically syncs .env.example templates with intelligent masked placeholders, and audits codebases for unconfigured environment variables.
⚡ Instant Quickstart • 💥 Problem vs. Solution • 📊 Feature Comparison • 🤖 GitHub Actions CI • 📦 Installation • ⚙️ CLI Command Reference • 🔬 Pipeline Architecture • 🚀 Benchmarks • 🧪 Test Suite • 🤝 Contributing
⚡ Instant Quickstart
Run immediately anywhere without installing via uvx:
# Verify active .env against .env.example
uvx --from envdoctor-cli envdoctor check
# Enforce bidirectional strict match (zero extra or missing keys)
uvx --from envdoctor-cli envdoctor check --strict
# Safely sync missing keys into .env.example with dummy placeholders
uvx --from envdoctor-cli envdoctor sync
# Audit source code for environment variables you forgot to define
uvx --from envdoctor-cli envdoctor audit ./src
Or install globally via pip:
pip install envdoctor-cli
💥 Problem vs. Solution
The Pain with Traditional Workflows
- Silent Production Crashes: A developer adds
STRIPE_WEBHOOK_SECRETlocally, merges the PR, but forgets.env.example. The app deploys and immediately crashes on boot withKeyErrororundefined. - Secret Leaks: When developers try to update
.env.examplemanually, real API tokens or database credentials accidentally get committed to Git. - Onboarding Friction: New team members clone the repo, copy
.env.exampleto.env, and spend hours debugging missing variables that nobody documented. - Dead Config Debt: Variables deleted from code years ago remain in
.envforever because nobody knows if they are still used.
The Character-Aligned Before & After
┌──────────────────────────────────────────────┬──────────────────────────────────────────────┐
│ BEFORE: Manual Drift & Production Outages │ AFTER: Automated Contract Integrity Gate │
├──────────────────────────────────────────────┼──────────────────────────────────────────────┤
│ $ git merge feature/billing-v2 │ $ envdoctor check --strict │
│ $ docker compose up -d │ │
│ [!] Container web crashed: │ 🩺 EnvDoctor v0.2.0 — Verifying contract... │
│ KeyError: 'STRIPE_WEBHOOK_SECRET' │ │
│ │ [!] MISSING IN .env (Required by template): │
│ * Why was it missing? │ - STRIPE_WEBHOOK_SECRET │
│ Developer forgot to update .env.example. │ - DATABASE_POOL_SIZE │
│ * Why didn't CI catch it? │ │
│ Test suites mock environment lookups. │ [!] DISCREPANCY DETECTED: │
│ * Onboarding a new teammate: │ .env.example requires 12 variables, │
│ "Hey, what should I put for REDIS_PORT?" │ but active .env only defines 10. │
│ "Oh, that was deprecated 6 months ago." │ │
│ │ [✗] Contract check failed with exit code 1. │
│ * Manual sync attempt: │ Run 'envdoctor sync' to auto-populate. │
│ Developer accidentally commits live API │ │
│ token into .env.example. Git leak incident!│ Result: CI blocks PR before deployment! │
└──────────────────────────────────────────────┴──────────────────────────────────────────────┘
📊 Feature Comparison
| Feature | EnvDoctor |
dotenv-linter |
direnv |
python-dotenv |
trufflehog |
|---|---|---|---|---|---|
| Zero Runtime Dependencies | ✅ Yes (Stdlib) | ❌ Needs Rust/binary | ❌ Needs Shell hook | ❌ Python library only | ❌ Heavy Go binary |
.env vs .env.example Check |
✅ Yes (Built-in) | ⚠️ Syntax only | ❌ No | ❌ No | ❌ No |
Secret-Safe Auto Sync (sync) |
✅ Yes (Masked) | ❌ No | ❌ No | ❌ No | ❌ No |
Codebase Variable Audit (audit) |
✅ Yes (Multi-lang) | ❌ No | ❌ No | ❌ No | ❌ No (Secrets only) |
| CI Quality Gate Exit Codes | ✅ Yes (0/1/2) | ✅ Yes | ❌ No | ❌ No | ✅ Yes |
| Never Leaks Inline Comments | ✅ Yes | ❌ N/A | ❌ N/A | ❌ N/A | ❌ N/A |
Machine JSON Output (--format json) |
✅ Yes | ⚠️ Limited | ❌ No | ❌ No | ✅ Yes |
| Cold Startup Time | < 15ms | < 10ms | ~25ms | ~40ms | ~250ms |
| GitHub Marketplace Action | ✅ Yes (@v1) |
⚠️ Third-party | ❌ No | ❌ No | ⚠️ Heavy action |
🤖 GitHub Actions CI/CD Quality Gate
Enforce environment contract integrity on every Pull Request. Drop EnvDoctor into .github/workflows/env-check.yml:
name: Environment Contract Verification
on:
pull_request:
branches: [main]
jobs:
env-check:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Verify .env contract with EnvDoctor
uses: umutgungorr/envdoctor@v1
with:
command: 'check'
env-file: '.env.example'
example-file: '.env.example'
args: '--strict'
📦 Installation
Option 1: Run instantly with uvx (No installation needed)
uvx --from envdoctor-cli envdoctor check
Option 2: Install via pip
pip install envdoctor-cli
Option 3: Pre-commit Hook Integration
Add to your .pre-commit-config.yaml:
repos:
- repo: https://github.com/umutgungorr/envdoctor
rev: v0.2.1
hooks:
- id: envdoctor-check
args: ["--strict"]
⚙️ CLI Command Reference
EnvDoctor provides three focused, high-speed diagnostic commands:
usage: envdoctor [-h] [-v] [--format {text,json}] [-o OUTPUT]
{check,sync,audit} ...
Zero-dependency .env linter, template synchronizer, and codebase auditor.
positional arguments:
{check,sync,audit}
check Validate active .env against template (.env.example)
sync Append missing keys to .env.example with safe placeholders
audit Scan codebase files for unconfigured environment variables
options:
-h, --help Show this help message and exit
-v, --version Show program version number and exit
--format {text,json} Output format (default: text)
-o, --output PATH Write output report to file
1. envdoctor check
Validates that all required variables declared in .env.example exist in .env.
# Standard check: fail if .env is missing variables required by .env.example
envdoctor check --env .env --example .env.example
# Strict mode: fail if .env has missing OR undocumented extra variables
envdoctor check --strict
# Allow declared variables to be empty strings
envdoctor check --allow-empty
Exit Codes:
0: All variables present and valid.1: Contract discrepancy detected (missing or empty variables).2: File not found or read/write I/O error.
2. envdoctor sync
Safely synchronizes .env.example by reading all keys from your local .env and generating intelligent, masked placeholder values.
# Preview changes without modifying file
envdoctor sync --dry-run
# Automatically update .env.example
envdoctor sync
Masking Intelligence Rules:
- Secret / API keys (
*_KEY,*_SECRET,*_TOKEN) $\rightarrow$your_api_key_here - Port numbers (
*_PORT,PORT) $\rightarrow$8080 - URLs (
*_URL,DATABASE_URL) $\rightarrow$postgres://user:password@localhost:5432/dbname - Hostnames (
*_HOST) $\rightarrow$localhost - Private inline comments (
# my private note) are never exported into.env.example.
3. envdoctor audit
Scans your application source code for direct environment lookups across Python, JavaScript, TypeScript, Go, Rust, and PHP:
# Audit entire source directory
envdoctor audit ./src
# Audit against a specific environment file
envdoctor audit ./src --env .env.production
Recognized Patterns:
- Python:
os.environ["KEY"],os.environ.get("KEY"),os.getenv("KEY") - JavaScript / TypeScript:
process.env.KEY,process.env["KEY"] - Go:
os.Getenv("KEY") - Rust:
env::var("KEY")
🔬 Pipeline Architecture
┌────────────────┐ ┌────────────────┐ ┌──────────────────────────────────┐
│ Active .env │ │ .env.example │ │ Application Source Code │
│ (Real Values) │ │ (Template) │ │ (Python / JS / TS / Go / Rust) │
└───────┬────────┘ └───────┬────────┘ └────────────────┬─────────────────┘
│ │ │
▼ ▼ ▼
┌───────────────────────────────────────┐ ┌──────────────────────────┐
│ Enterprise .env Parser │ │ Multi-Language Scanner │
│ * Quoted & multiline strings │ │ * Regex pattern cache │
│ * Escaped characters & exports │ │ * Ignores node_modules │
└──────────────────┬────────────────────┘ └────────────┬─────────────┘
│ │
▼ ▼
┌───────────────────────────────────────┐ ┌──────────────────────────┐
│ Differ Engine │ │ Auditor Engine │
│ * Missing keys detection │ │ * Unconfigured env vars │
│ * Bidirectional strict symmetry │ │ * Stale / dead vars │
└───────┬───────────────────────────────┘ └────────────┬─────────────┘
│
├──► check ──► [ Exit 0: Clean | Exit 1: Discrepancy ]
│
└──► sync ──► [ Secret-Safe Placeholder Generator ] ──► Updates .env.example
🚀 Verified Benchmarks
Measured on standard developer hardware (AMD Ryzen 9 / Apple M-series):
| Metric | Result | Industry Alternative |
|---|---|---|
| Cold Startup Time | < 15ms | 250ms+ (Node/Go CLI tools) |
| Parsing 1,000 .env lines | < 4ms | ~20ms |
| Auditing 50,000 LOC | < 110ms | 1,500ms+ (AST-based linters) |
| Memory Footprint | < 6 MB | 50MB+ (V8 / Electron wrappers) |
| External Dependencies | 0 | 12+ transitive packages |
🧪 Test Suite
EnvDoctor maintains a 100% test pass rate across all major operating systems and Python versions:
# Run pytest with coverage report
uv run --with pytest pytest contract_tests tests -v
============================= test session starts =============================
platform win32 / linux / darwin -- Python 3.9 - 3.14
collected 32 items
contract_tests/test_contract.py .. [ 6%]
tests/test_auditor.py ... [ 15%]
tests/test_cli.py ......... [ 43%]
tests/test_differ.py ..... [ 59%]
tests/test_parser.py ....... [ 81%]
tests/test_syncer.py ...... [100%]
============================= 32 passed in 0.31s ==============================
🤝 Contributing
Contributions are warmly welcomed! Please read CONTRIBUTING.md and CODE_OF_CONDUCT.md for local development setup and guidelines.
# Clone the repository
git clone https://github.com/umutgungorr/envdoctor.git
cd envdoctor
# Run tests
uv run --with pytest pytest contract_tests tests -v
# Run linter
uv run --with ruff ruff check .
⚡ Part of the Developer Diagnostics Suite
EnvDoctor is a core pillar of the zero-dependency Developer Diagnostics Suite by @umutgungorr:
- 🌲 PortTree: Dev socket tree scanner, Docker proxy unmasker, and process-tree killer.
- ⚡ LogShrink: Zero-config CLI stream filter that collapses noisy polling logs and auto-boxes stack traces.
- 🩺 RepoPulse: Git forensic health, architectural hotspot churn, and bus-factor risk engine.
- 💊 EnvDoctor: Zero-dependency
.envdrift synchronizer, secret-safe generator, and codebase config auditor.
📖 Project Case Study
EnvDoctor is an open-source project by Umut Güngör. Read the EnvDoctor case study for its design philosophy, benchmarks, and real-world impact.
📄 License
This project is licensed under the terms of the MIT License.
Copyright (c) 2026 Umut Güngör.
Metadata
Release files for envdoctor-cli 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| envdoctor_cli-0.2.1.tar.gz | 655.9 kB | Without provenance | Details for envdoctor_cli-0.2.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| envdoctor_cli-0.2.1-py3-none-any.whl | Python 3 | none | any | Details for envdoctor_cli-0.2.1-py3-none-any.whl |
Total release size: 674.9 kB
Release files / envdoctor_cli-0.2.1.tar.gz
| Download URL | envdoctor_cli-0.2.1.tar.gz |
|---|---|
| Size | 655.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2bb0c5da0a6ee4c86c8c9ec985776b01f227b01e4ffac72e681eab09ae3347fa
|
|
BLAKE2b-256 checksum How to use checksums |
4c209b2a12e0c1dceb905a50b32a08f1b2fad04e3e9157a1a604816ac8836045
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.4 {"installer":{"name":"uv","version":"0.12.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / envdoctor_cli-0.2.1-py3-none-any.whl
| Download URL | envdoctor_cli-0.2.1-py3-none-any.whl |
|---|---|
| Size | 19.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
46c4f2340dcadc3b028f125f5f7223dd0e20e32b6cd76471bc5d87a62c77694f
|
|
BLAKE2b-256 checksum How to use checksums |
bd286024c6def7e3b54fc20c03b2de37fdf7d835a8fc1404d52cb72073e52f85
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.4 {"installer":{"name":"uv","version":"0.12.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for envdoctor-cli 0.2.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.