EnvDoctor 🩺
Zero-dependency
.envand.env.examplelinter, synchronizer, and code auditor CLI with JSON output.
Prevent missing environment variables, eliminate production deployment crashes, and keep your config templates perpetually synchronized.
$ envdoctor check --strict
🩺 EnvDoctor v0.2.0 — Verifying environment contract...
[!] MISSING IN .env (Required by .env.example):
- STRIPE_SECRET_KEY
- DATABASE_POOL_SIZE
[!] DISCREPANCY DETECTED:
.env.example requires 12 variables, but active .env only defines 10.
[✗] Contract check failed with exit code 1.
(To safely sync missing placeholders, run: envdoctor sync)
💥 The Problem
In modern software projects, environment variables are essential for configuration and secrets. However, teams constantly face these issues:
- Silent Production Outages: A developer adds a new variable (e.g.
STRIPE_KEYorDATABASE_URL) to their local.env, forgets to update.env.example, and production crashes immediately upon deployment. - Onboarding Friction: New team members clone the repo, copy
.env.exampleto.env, but discover missing or undocumented variables only after runtime errors. - Dead / Stale Config Clutter: Variables deleted from source code remain lingering in
.envfiles indefinitely because nobody knows if they are still needed.
EnvDoctor solves this entirely with three focused, zero-dependency tools: check, sync, and audit.
🌟 Key Features
- Zero External Dependencies: Built 100% on the Python Standard Library (
re,pathlib,argparse,json,os). Runs immediately anywhere without package installation overhead. - Enterprise
.envParser: Handles single/double quotes, multiline values across physical lines (certificates, JSON blobs), escaped quotes (\",\'), inline comments (#), andexportstatements. - Machine-Parseable JSON Output:
--format jsonsupport across all subcommands (check,sync,audit) for easy integration into automation pipelines. - Safe Template Synchronizer (
sync): Automatically populates.env.exampleusing keys from.env, substituting real secrets with intelligent masked placeholders (e.g.your_api_key_here,8080,localhost). - Codebase AST / Regex Auditor (
audit): Recursively scans Python (os.environ,os.getenv) and JavaScript/TypeScript (process.env) files to find environment variables used in code but missing from.env. - Deterministic Exit Codes:
0(clean),1(contract violations / missing keys),2(CLI / file not found errors).
🚀 Quick Start
1. Installation
Install via pip:
pip install .
Or run directly without installation:
python -m envdoctor --help
🛠️ Commands & Usage
1. envdoctor check (Compare & Lint)
Compare your local .env against the reference .env.example:
# Standard check (fails if required template variables are missing locally)
envdoctor check
# Custom file paths
envdoctor check --env .env.local --example .env.template
# Strict mode (fails if template is missing any local variables or values are empty)
envdoctor check --strict
# Machine-readable JSON output
envdoctor --format json -o diff_report.json check
Sample Output:
====================================================================
🩺 EnvDoctor Health Check Report
====================================================================
Active Env File: .env (12 variables)
Reference Template: .env.example (14 variables)
--------------------------------------------------------------------
[!] CRITICAL: Variables declared in .env.example but MISSING in .env:
- REDIS_URL
- STRIPE_WEBHOOK_SECRET
--------------------------------------------------------------------
✗ FAILED: Environment discrepancies detected. Please resolve above issues.
====================================================================
2. envdoctor sync (Safe Template Generation)
Safely sync newly added local .env variables to .env.example without exposing real secrets:
# Preview what would be appended
envdoctor sync --dry-run
# Append new variables with masked dummy placeholders
envdoctor sync
EnvDoctor automatically generates safe values:
PORT$\rightarrow$8080DATABASE_URL$\rightarrow$postgresql://postgres:password@localhost:5432/my_databaseSTRIPE_KEY$\rightarrow$your_stripe_key_hereDEBUG$\rightarrow$true
3. envdoctor audit (Scan Source Code)
Scan your application code to find environment variables that aren't defined in .env:
# Scan current directory
envdoctor audit
# Scan specific directories
envdoctor audit src/ backend/ --env .env
# Export audit findings to JSON
envdoctor --format json -o audit.json audit src/
Sample Output:
====================================================================
🩺 EnvDoctor Codebase Audit Report
====================================================================
Scanned Paths: src/, backend/
Referenced Envs: 18 variables across 42 usages
Known in .env: 16 variables
--------------------------------------------------------------------
[!] MISSING IN .env (Code references these, but they are not defined):
- ANALYTICS_ID (src/services/telemetry.py:14)
[*] STALE VARIABLES (Defined in .env, but never referenced in scanned code):
- LEGACY_FEATURE_V1
====================================================================
⚙️ CLI Options & Deterministic Exit Codes
usage: envdoctor [-h] [--version] [--format {text,json}] [-o OUTPUT]
[--no-color] [-q] [-v] {check,sync,audit} ...
| Exit Code | Meaning |
|---|---|
0 |
Success: Environment is in sync / clean audit / dry-run |
1 |
Discrepancy detected: Missing variables in .env, strict failure, or missing code variables |
2 |
Error: File not found or invalid CLI arguments |
🤖 CI/CD Integration (GitHub Actions)
Catch missing environment variables before merging PRs:
name: Configuration Integrity
on: [push, pull_request]
jobs:
envdoctor:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Verify Environment Template
run: |
python -m envdoctor --format json check --strict --example .env.example --env .env.example
🧪 Running Tests
uv run --with pytest pytest
📄 License
MIT License. See LICENSE for details.
Release files for envdoctor-cli 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| envdoctor_cli-0.2.0.tar.gz | 645.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| envdoctor_cli-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 661.2 kB
Release files / envdoctor_cli-0.2.0.tar.gz
| Download URL | envdoctor_cli-0.2.0.tar.gz |
|---|---|
| Size | 645.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a61a7828b2280f6ef1ebb4e72aee8db4ec08c22ae8ecc90acef8d9ef0bcb189a
|
|
BLAKE2b-256 checksum How to use checksums |
cd078d062d836be2caa7c9ca580fa8586c7e2c06f3b005ae26c86625d43bc4dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / envdoctor_cli-0.2.0-py3-none-any.whl
| Download URL | envdoctor_cli-0.2.0-py3-none-any.whl |
|---|---|
| Size | 15.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
123e522e2a7fb7788d8c322de77e37952a5d6f5d19c4ab14fe5405a0e7746439
|
|
BLAKE2b-256 checksum How to use checksums |
3079a7afc197a323c1234114402991c8061b5d3199582eab8f668d028b2fee70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|