AI-powered .env file manager - scan, validate, and generate environment variable configurations.
Stop manually maintaining .env.example files. Let unenv automatically detect environment variables from your codebase.
unenv scans your code for environment variables, generates documented .env.example files, and validates your configuration. Works with Node.js, Python, Ruby, Go, and PHP.
Before:
# New developer joins the team
New Dev: "What environment variables do I need?"
You: "Check the .env.example file"
New Dev: "It's outdated and missing half the variables"
You: "Oh yeah, I forgot to update it..."
# Meanwhile in production:
*app crashes*
Error: Missing required environment variable: REDIS_URL
# That variable was added 2 months ago
# Nobody updated .env.example
# Nobody told DevOpsAfter:
$ unenv scan
Missing from .env (3):
• DATABASE_URL (used in src/db.js:15)
• API_KEY (used in src/api.js:8)
• REDIS_HOST (used in src/cache.js:23)
$ unenv generate
Created .env.example with 12 variables
$ unenv check --strict
All variables configured correctlyReal pain points:
.env.examplegets outdated immediately- New developers don't know what variables they need
- Production breaks because of missing config
- No visibility into where variables are actually used
- Manual maintenance is tedious and error-prone
unenv scans your code, finds all environment variables, and keeps documentation in sync automatically.
npm install -g unenvOr use without installing:
npx unenv scan# Scan your project
unenv scan
# Generate .env.example
unenv generate
# Validate configuration
unenv check$ git clone https://github.com/company/api-service.git
$ cd api-service
$ npm install
# What environment variables do I need?
$ unenv scan
Analyzed 38 files
Found 15 environment variables
Missing from .env (15):
• DATABASE_URL (used in src/db/connection.js:12)
• JWT_SECRET (used in src/auth/jwt.js:5)
• AWS_ACCESS_KEY_ID (used in src/storage/s3.js:8)
• AWS_SECRET_ACCESS_KEY (used in src/storage/s3.js:9)
• REDIS_URL (used in src/cache/redis.js:7)
• STRIPE_API_KEY (used in src/payments/stripe.js:14)
• SMTP_HOST (used in src/email/mailer.js:19)
• SMTP_PORT (used in src/email/mailer.js:20)
• SMTP_USER (used in src/email/mailer.js:21)
• SMTP_PASS (used in src/email/mailer.js:22)
• NODE_ENV (used in src/config/index.js:3)
• PORT (used in src/server.js:45)
• LOG_LEVEL (used in src/logger.js:8)
• SESSION_SECRET (used in src/middleware/session.js:11)
• API_RATE_LIMIT (used in src/middleware/rate-limit.js:6)
# Generate template
$ unenv generate
Created .env.example with 15 variables
# Copy and fill in values
$ cp .env.example .env
$ nano .env # fill in real values
# Verify everything is configured
$ unenv check
Configuration checked - all variables present ✓# .github/workflows/test.yml
name: Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
# Check environment configuration
- name: Validate environment variables
run: npx unenv check --strict
# This fails if:
# - Required variables are missing from .env.example
# - Variables in code aren't documentedOutput on failure:
Configuration checked
Missing Variables (2):
• NEW_API_ENDPOINT
Used in: src/integrations/new-service.js:15
• FEATURE_FLAG_X
Used in: src/features/x.js:8
Error: Missing required environment variables
$ unenv check
Configuration checked
Environment Configuration Report
═══════════════════════════════════════════════════════
Summary:
Required variables: 18
Configured: 23
Missing: 0
Unused: 5
Unused Variables (5):
These are in .env but not used in your code
• OLD_PAYMENT_API_KEY
Possibly left over from migration to Stripe
• LEGACY_DATABASE_URL
May be safe to remove
• FEATURE_TOGGLE_BETA
Feature might be fully launched now
• TWILIO_AUTH_TOKEN
Switched to SendGrid 3 months ago?
• REDIS_PASSWORD
Redis now uses REDIS_URL
Consider removing unused variables or checking if they're still needed.Clean up:
# Review and remove from .env
$ nano .env # remove unused vars
# Verify
$ unenv check
Configuration checked - all variables present ✓
No unused variables found# Development environment
$ unenv check --env .env.development
Configuration checked - all variables present ✓
# Staging environment
$ unenv check --env .env.staging
Missing Variables (1):
• DATABASE_URL
Used in: src/db/connection.js:12
# Production environment
$ unenv check --env .env.production
Missing Variables (2):
• SENTRY_DSN
Used in: src/monitoring/sentry.js:5
• CDN_URL
Used in: src/assets/cdn.js:8
Unused Variables (1):
• DEBUG_MODE
(not used in production - should be removed)Use case: Catch environment-specific configuration issues before deploying.
$ unenv scan --verbose
DATABASE_URL:
- src/db/connection.js:12
- src/models/user.js:23
- src/models/post.js:19
- tests/integration/db.test.js:8
- scripts/migrate.js:15
JWT_SECRET:
- src/auth/jwt.js:5
- src/middleware/auth.js:34
- tests/unit/auth.test.js:12
AWS_ACCESS_KEY_ID:
- src/storage/s3.js:8
- src/backup/uploader.js:44
$ unenv scan --verbose --json > env-usage-map.json
# Now you can:
# - See which files depend on each variable
# - Understand impact of changing a variable
# - Plan refactoring (e.g., moving AWS creds to IAM roles)
# - Generate dependency graphsScan your codebase and compare with .env file.
$ unenv scanOutput:
Analyzed 42 files
Found 12 environment variables
Missing from .env (3):
• DATABASE_URL
Used in src/db.js:15
• API_KEY
Used in src/api.js:8
• REDIS_HOST
Used in src/cache.js:23
Found in .env (9):
PORT, NODE_ENV, JWT_SECRET, AWS_REGION, SMTP_HOST,
SMTP_USER, SMTP_PASS, LOG_LEVEL, SESSION_SECRET
Options:
-d, --dir <directory> Directory to scan (default: current)
-i, --ignore <patterns> Comma-separated ignore patterns
--json Output as JSON
-v, --verbose Show all file locations for each variable
Verbose output:
$ unenv scan --verbose
DATABASE_URL:
- src/db.js:15
- src/models/user.js:8
- tests/integration/db.test.js:12Generate documented .env.example file with smart categorization.
$ unenv generateOutput:
Analyzed 42 files
Created .env.example with 12 variables
Preview:
────────────────────────────────────────
# Generated by unenv
# Last updated: 2025-02-05
# Database
# ────────────────────────────────────────
# Database connection string (URL format)
# Used in: src/db.js
DATABASE_URL=
# Redis host for caching
# Used in: src/cache.js
REDIS_HOST=
# Authentication
# ────────────────────────────────────────
# JWT secret key - keep secret! - DO NOT COMMIT!
# Used in: src/auth.js
JWT_SECRET=
# API key for external service - keep secret!
# Used in: src/api.js
API_KEY=
...
Options:
-d, --dir <directory> Directory to scan
-o, --output <file> Output file (default: .env.example)
-i, --ignore <patterns> Ignore patterns
--no-categorize Don't group by category
Categories automatically detected:
- Database (DB, DATABASE, SQL, MONGO, REDIS, etc.)
- Authentication (AUTH, JWT, SECRET, TOKEN, KEY, etc.)
- API & Services (API, SERVICE, ENDPOINT, etc.)
- Cloud & Infrastructure (AWS, GCP, AZURE, S3, etc.)
- Application (PORT, NODE_ENV, DEBUG, etc.)
- Email (SMTP, MAIL, EMAIL, etc.)
- Payment (STRIPE, PAYPAL, PAYMENT, etc.)
Validate your configuration - find missing and unused variables.
$ unenv checkOutput:
Configuration checked
Environment Configuration Report
═══════════════════════════════════════════════════════
Summary:
Required variables: 12
Configured: 10
Missing: 2
Unused: 3
Missing Variables (2):
These are used in your code but not defined in .env
• API_KEY
Category: API & Services
Used in: src/api.js:8
• REDIS_HOST
Category: Database
Used in: src/cache.js:23
Unused Variables (3):
These are in .env but not used in your code
• OLD_API_KEY
• LEGACY_DB_URL
• UNUSED_TOKEN
Consider removing unused variables or checking if they're still needed.
Options:
-d, --dir <directory> Directory to scan
-e, --env <file> Env file to check (default: .env)
-i, --ignore <patterns> Ignore patterns
--fix Automatically add missing variables to .env
--strict Exit with error code if issues found (CI/CD)
Auto-fix example:
$ unenv check --fix
🔧 Auto-fixing missing variables...
✓ Added 2 variable(s) to .env
⚠️ Values are empty - please fill them in manuallyThe --fix flag:
- Adds missing variables to your
.envfile - Groups them by category with helpful comments
- Leaves values empty for manual entry
- Never overwrites existing values
- Great for quickly scaffolding new environment variables
CI/CD usage:
# Fail build if environment is misconfigured
unenv check --strictprocess.env.API_KEY
process.env['DATABASE_URL']
const key = process.env.SECRET_KEYos.getenv('API_KEY')
os.environ['DATABASE_URL']
os.environ.get('REDIS_HOST')ENV['API_KEY']
ENV.fetch('DATABASE_URL')os.Getenv("API_KEY")getenv('API_KEY')
$_ENV['DATABASE_URL']
$_SERVER['REDIS_HOST']# Ignore test files and specific directories
unenv scan --ignore "tests,__tests__,*.test.js,node_modules"# Get machine-readable output for scripting
unenv scan --json > env-report.json# Check production environment
unenv check --env .env.production
# Generate for staging
unenv generate --output .env.staging.exampleGitHub Actions:
- name: Validate environment variables
run: npx unenv check --strictGitLab CI:
test:env:
script:
- npx unenv check --strict- Commit
.env.example- Share structure with your team, not secrets - Never commit
.env- Add it to.gitignore - Run
unenv checkin CI - Catch missing variables before deployment - Update regularly - Re-run
unenv generateafter adding features - Review unused variables - Clean up old config periodically
- Use
--strictin CI/CD - Fail builds on missing variables
unenvonly reads your code - never modifies.envfiles- Automatically checks if
.envis in.gitignore - Highlights sensitive variables (secrets, keys, passwords)
- Never logs or transmits actual environment values
- All processing happens locally
Full .env.example generated by unenv:
# Generated by unenv
# Last updated: 2025-02-05T14:30:00.000Z
#
# This file documents all environment variables used in this project.
# Copy this to .env and fill in the values.
# Database
# ────────────────────────────────────────
# Database connection string (URL format)
# Used in: src/db.js
DATABASE_URL=
# Redis host for caching
# Used in: src/cache.js
REDIS_HOST=
# Redis port (number)
# Used in: src/cache.js
REDIS_PORT=
# Authentication
# ────────────────────────────────────────
# JWT secret key - keep secret! - DO NOT COMMIT!
# Used in: src/auth.js
JWT_SECRET=
# API key for external service - keep secret!
# Used in: src/api.js
API_KEY=
# Application
# ────────────────────────────────────────
# Environment: development | production | test
# Used in: src/config.js
NODE_ENV=
# Application port (number)
# Used in: src/server.js
PORT=
# Enable debug logging (boolean)
# Used in: src/logger.js
DEBUG=- Onboarding - New developers know exactly what variables they need
- CI/CD - Validate environment before deployment
- Documentation - Always up-to-date variable list
- Debugging - Find where variables are used across codebase
- Cleanup - Identify unused variables to remove
- Security audits - List all sensitive variables
Problem: Variables in template strings aren't found.
// Not detected ❌
const url = `https://${process.env.API_HOST}/api`;
// Detected ✅
const host = process.env.API_HOST;
const url = `https://${host}/api`;Cause: Pattern matching doesn't parse JavaScript template literals deeply.
Workaround:
// Extract to separate line
const API_HOST = process.env.API_HOST;
const url = `https://${API_HOST}/api`;
// Or use explicit property access
const url = `https://${process.env['API_HOST']}/api`;Problem: Dynamic variable access isn't detected.
// Not detected ❌
const env = 'production';
const dbUrl = process.env[`${env.toUpperCase()}_DATABASE_URL`];
// Detected ✅
const dbUrl = process.env.PRODUCTION_DATABASE_URL;Cause: unenv uses static analysis, can't evaluate runtime expressions.
Solution: Use explicit variable names or add comments:
// UNENV: PRODUCTION_DATABASE_URL, DEVELOPMENT_DATABASE_URL
const env = process.env.NODE_ENV || 'development';
const dbUrl = process.env[`${env.toUpperCase()}_DATABASE_URL`];Problem: Scanned variables don't match what was previously in .env.example.
Cause: Code changed, .env.example wasn't updated.
Solution:
# Backup existing
cp .env.example .env.example.backup
# Generate fresh version
unenv generate
# Compare
diff .env.example.backup .env.example
# Manually merge custom comments/valuesBest practice: Re-run unenv generate after major features or during code reviews.
Problem: Variables in comments are detected as usage.
// TODO: Add process.env.NEW_FEATURE_FLAG later
// This isn't actually used yet, but unenv detects it
// Workaround: Use generic terms in comments
// TODO: Add feature flag environment variable laterLimitation: Pattern matching can't distinguish code from comments perfectly.
Problem: .env has variables that aren't in code, but unenv doesn't warn.
Cause: unenv scans code → env, not env → code.
Solution:
# Use check command to find unused variables
unenv check
Unused Variables (3):
• OLD_API_KEY
• LEGACY_DATABASE_URL
• UNUSED_TOKEN
# Review and remove from .envProblem: Monorepo with multiple services, each using different env vars.
Scenario:
monorepo/
├── services/
│ ├── api/ (uses DATABASE_URL, JWT_SECRET)
│ ├── frontend/ (uses API_ENDPOINT)
│ └── worker/ (uses QUEUE_URL, DATABASE_URL)
└── .env (shared)
Solution:
# Option 1: Scan each service separately
cd services/api
unenv generate --output ../../.env.api.example
cd services/frontend
unenv generate --output ../../.env.frontend.example
# Option 2: Scan entire monorepo
cd monorepo/
unenv scan --dir services/
# Detects all variables across all services
# Option 3: Use service-specific .env files
# Each service has its own .env
services/api/.env
services/frontend/.env
services/worker/.envProblem: Developer accidentally commits real secrets to .env.example.
# ❌ DANGER - Real secret in .env.example
API_KEY=sk_live_abcd1234...
# ✅ CORRECT - Placeholder
API_KEY=your_api_key_herePrevention:
# Use unenv generate (always creates placeholders)
unenv generate
# Add git pre-commit hook
#!/bin/bash
# .git/hooks/pre-commit
if git diff --cached .env.example | grep -E "sk_live|pk_live|secret_|password=.{8,}"; then
echo "❌ Possible secret detected in .env.example"
exit 1
fiDetection:
# Check for suspicious patterns
grep -E "sk_|pk_|[a-zA-Z0-9]{32,}" .env.example
# Review before committing
git diff .env.exampleProblem: Scanning detects env vars from node_modules.
$ unenv scan
Found 127 environment variables
Including:
• DEBUG (from node_modules/debug/src/index.js)
• NODE_ENV (from node_modules/express/lib/application.js)
# ... 100+ moreSolution:
# Ignore node_modules (default behavior)
unenv scan --ignore "node_modules,vendor"
# Or be more specific
unenv scan --dir src/Problem: Ignore patterns don't work on Windows.
Cause: Windows uses \ instead of / for paths.
Solution:
# Use forward slashes (works on all platforms)
unenv scan --ignore "node_modules,dist,build"
# Avoid backslashes
# ❌ --ignore "node_modules\dist"
# ✅ --ignore "node_modules,dist"Problem: .env file committed to git with secrets.
Detection:
# Check if .env is tracked
git ls-files | grep "^\.env$"
# If output: .env is tracked ❌Fix:
# Add to .gitignore
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
echo ".env.*.local" >> .gitignore
# Remove from git (keep local file)
git rm --cached .env
# Commit
git commit -m "chore: remove .env from tracking"
# Verify
unenv check # Should warn if .env not in .gitignoreProblem: Framework-specific prefixes not detected.
Vite:
// Not detected by default ❌
const apiUrl = import.meta.env.VITE_API_URL;React (CRA):
// Not detected by default ❌
const key = process.env.REACT_APP_API_KEY;Current workaround: unenv detects these if using standard patterns.
Future improvement: Add framework-specific detection modes.
Problem: docker-compose.yml references env vars not in code.
# docker-compose.yml
services:
db:
image: postgres:15
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD} # Not in app codeSolution:
# Manually add to .env.example
echo "# Docker Compose variables" >> .env.example
echo "DB_PASSWORD=" >> .env.example
# Or scan docker-compose.yml separately
grep -oE '\$\{[^}]+\}' docker-compose.yml | tr -d '${}'Problem: CI fails with missing variables that work locally.
Cause: Different .env files between local and CI.
Debug:
# In CI, print what's detected
unenv scan --json
# Compare with local
unenv scan --json > local-scan.json
# Check diff
diff local-scan.json ci-scan.jsonCommon causes:
.env.localexists locally but not in CI- Git ignored files not in CI
- Different Node.js/Python versions
Fix:
# Use consistent .env.example
cp .env.example .env # In CI setup
# Or validate against .env.example
unenv check --env .env.example --strictProblem: Scanning 1000+ files takes too long.
Solution:
# Scan only specific directories
unenv scan --dir src/,lib/
# Ignore test files
unenv scan --ignore "**/*.test.js,**/*.spec.js,tests/"
# Use multiple workers (if implemented)
unenv scan --workers 4Performance tip: Add unenv scan to pre-commit hooks, not on every save.
Problem: Can't distinguish between required and optional env vars.
// Required
const dbUrl = process.env.DATABASE_URL; // App crashes if missing
// Optional
const debug = process.env.DEBUG || false; // Has defaultCurrent limitation: unenv treats all variables as equal.
Workaround: Use comments in .env.example:
# Required variables
DATABASE_URL=
# Optional (has defaults)
DEBUG=false
LOG_LEVEL=infoFuture feature: Detect default values and mark as optional.
Slow:
unenv scan
# Scans entire project including node_modules, dist, etc.Fast:
unenv scan --dir src/,lib/
# Scans only source codeImpact: 10x faster for large projects.
Create .unenvignore (similar to .gitignore):
# .unenvignore
node_modules/
dist/
build/
coverage/
*.test.js
*.spec.ts
Usage:
unenv scan
# Automatically respects .unenvignoreFor CI/CD with unchanged code:
# Generate cache key based on file hashes
HASH=$(find src/ -type f -name "*.js" -exec md5sum {} \; | md5sum | cut -d' ' -f1)
# Check cache
if [ -f "unenv-cache-$HASH.json" ]; then
echo "Using cached scan results"
cat "unenv-cache-$HASH.json"
else
unenv scan --json > "unenv-cache-$HASH.json"
fiSlow:
cd service-1 && unenv scan
cd service-2 && unenv scan
cd service-3 && unenv scanFast:
# Scan in parallel
(cd service-1 && unenv scan) &
(cd service-2 && unenv scan) &
(cd service-3 && unenv scan) &
waitInefficient:
unenv scan | grep "DATABASE_URL" | awk '{print $2}'Efficient:
unenv scan --json | jq -r '.variables[] | select(.name == "DATABASE_URL")'Only scan changed files:
# Git hook: pre-commit
CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E "\.(js|ts|py)$")
if [ -n "$CHANGED_FILES" ]; then
unenv scan --files $CHANGED_FILES
fiIf you have consistent patterns:
# Only scan top-level files
unenv scan --max-depth 3
# Skip deeply nested directoriesSlow:
unenv scan
unenv check
unenv generateFast:
# Combine into single scan operation
unenv verify --generate --check
# (if implemented as single command)If using multiple languages:
# Only scan JavaScript files
unenv scan --lang javascript
# Skip Python files if not using Python
unenv scan --exclude-lang pythonContinuous scanning during dev:
# Watch files and re-scan on changes
unenv watch
# Or use nodemon/chokidar
nodemon --watch src/ --exec "unenv scan"A: No. All processing is 100% local. unenv:
- Never sends data to external servers
- Never logs actual variable values
- Only scans your local files
- Open-source - audit the code yourself
A: Not automatically (yet). Current limitations:
- Treats all
process.env.Xas equally important - Doesn't detect default values
Workaround:
// Use comments to mark as optional
const debug = process.env.DEBUG || false; // UNENV:OPTIONAL
// Or in .env.example
# Required
DATABASE_URL=
# Optional (has defaults)
DEBUG=falseRoadmap: Automatic detection of default values planned for v2.0.
A: Multiple approaches:
Option 1: Separate .env files
.env.development
.env.staging
.env.production
.env.example # Template for all
# Validate each
unenv check --env .env.development
unenv check --env .env.staging
unenv check --env .env.productionOption 2: Single .env with environment markers
# .env.example
# === Development ===
DEV_DATABASE_URL=
DEV_API_KEY=
# === Production ===
PROD_DATABASE_URL=
PROD_API_KEY=Option 3: Environment-specific scanning
# Scan for production code only
unenv scan --dir src/production/A: Yes! Several strategies:
Strategy 1: Root-level .env
# Scan entire monorepo
unenv scan --dir packages/
# Generate unified .env.example
unenv generateStrategy 2: Per-package .env
# Each package has own .env
packages/api/.env
packages/frontend/.env
# Scan each separately
cd packages/api && unenv generate
cd packages/frontend && unenv generateStrategy 3: Shared + local
# Root .env for shared vars (DB, Redis)
/.env
# Package-specific vars
/packages/api/.env.local
/packages/frontend/.env.localA: Partially. Works with:
Standard patterns:
// ✅ Detected
process.env.VITE_API_URL
process.env.REACT_APP_API_KEY
process.env.NEXT_PUBLIC_URLFramework-specific patterns:
// ⚠️ May not detect
import.meta.env.VITE_API_URL // ViteWorkaround:
// Extract to variable first
const VITE_API_URL = import.meta.env.VITE_API_URL;Future: Framework-specific scanners planned.
A: Examples for major platforms:
GitHub Actions:
name: Env Check
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Validate .env configuration
run: |
npx unenv check --strict
npx unenv scan --json > env-report.json
- name: Upload report
uses: actions/upload-artifact@v3
with:
name: env-report
path: env-report.jsonGitLab CI:
env-check:
stage: validate
script:
- npm install -g unenv
- unenv check --strict
- unenv generate --output .env.example.new
- diff .env.example .env.example.new || exit 1
only:
- merge_requestsJenkins:
stage('Env Validation') {
steps {
sh 'npx unenv check --strict'
sh 'npx unenv scan --json > env-report.json'
archiveArtifacts 'env-report.json'
}
}A: Not directly (yet), but you can combine:
AWS Secrets Manager:
# Fetch secrets
aws secretsmanager get-secret-value --secret-id prod/myapp | \
jq -r '.SecretString' > .env.production
# Validate against code
unenv check --env .env.productionHashiCorp Vault:
# Export secrets to .env
vault kv get -format=json secret/myapp | \
jq -r '.data.data | to_entries[] | "\(.key)=\(.value)"' > .env
# Scan and compare
unenv checkFuture feature: Direct integration with secret managers planned for v2.0.
A: unenv primarily scans application code. For scripts:
Bash scripts:
# Variables like $API_KEY won't be detected automatically
# Workaround: Add comment marker
# UNENV: API_KEY, DATABASE_URL
source .envPython scripts:
# These ARE detected ✅
import os
api_key = os.getenv('API_KEY')
db_url = os.environ['DATABASE_URL']A: Use ignore patterns:
# Exclude test files
unenv scan --ignore "**/*.test.js,**/*.spec.ts,tests/"
# Or create .unenvignore
echo "**/*.test.js" >> .unenvignore
echo "tests/" >> .unenvignoreAlternatively, separate test vars:
# .env.example - production vars only
DATABASE_URL=
API_KEY=
# .env.test.example - test-specific
TEST_DATABASE_URL=
MOCK_API_KEY=A: Partially, with --fix:
unenv check --fix
# What it does:
# ✅ Adds missing variables (as empty)
# ✅ Adds comments/categorization
# ❌ Doesn't remove unused variables (safety)
# ❌ Doesn't fill in values (security)After auto-fix:
# .env (updated)
DATABASE_URL= # ← Added, needs value
API_KEY= # ← Added, needs value
# Existing vars untouched
NODE_ENV=developmentManual review still required for values and removing unused vars.
- Framework-specific scanners (Vite, Next.js, React Native)
-
.unenvignorefile support - Better TypeScript support (
import.meta.env, typed variables) - Parallel scanning for monorepos
- Required vs optional variable detection
- Secret manager integration (AWS, Vault, Azure KeyVault)
- Watch mode for continuous validation
- Web dashboard for visualization
- Docker Compose .yml scanning
- Kubernetes ConfigMap/Secret generation
- AST-based parsing (100% accuracy)
- Variable dependency graph
- Auto-fix suggestions (with AI?)
- Multi-language support (Java, C#, Rust)
- Team collaboration features
- Generate from OpenAPI/Swagger specs
- Integration with Terraform/Pulumi
- Environment diff tool (compare dev/staging/prod)
- Slack/Discord notifications for env changes
- VS Code extension
Vote on features: GitHub Discussions
# Clone repo
git clone https://github.com/muinmomin/unenv.git
cd unenv
# Install dependencies
npm install
# Link locally
npm link
# Test on a project
cd /path/to/your/project
unenv scan
# Run tests
npm test
# Build
npm run build
# Publish (maintainers only)
npm publishContributions welcome!
Ideas for improvement:
- Support more languages (Rust, Java, C#, etc.)
- Detect required vs optional variables
- Integration with secret managers (AWS Secrets Manager, Vault, etc.)
- Web UI for visualization
- Auto-generate from OpenAPI specs
- Support for nested .env files
How to contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/rust-support) - Make your changes
- Add tests for new functionality
- Submit a pull request
Please include:
- Example code patterns you're adding support for
- Test cases for new features
- Documentation updates
Adding new language support:
- Add pattern to
src/scanners/:
// src/scanners/rust.js
export const rustPatterns = [
/std::env::var\("([^"]+)"\)/g,
/env::var_os\("([^"]+)"\)/g,
];- Add tests:
// tests/rust.test.js
test('detects Rust env::var', () => {
const code = 'let key = std::env::var("API_KEY").unwrap();';
const vars = scan(code, { lang: 'rust' });
expect(vars).toContain('API_KEY');
});- Update docs
Adding new features:
- Open an issue first to discuss
- Write tests before implementation (TDD)
- Update README with examples
- Ensure backward compatibility
- Detects variables by pattern matching (not full AST parsing)
- May miss dynamically constructed variable names
- Doesn't validate variable formats or types
- No support for variable substitution/interpolation
- Template literals with env vars may not be detected
- Framework-specific patterns (import.meta.env) limited support
For 100% accuracy: Manual review of .env.example is still recommended.
MIT © muin
- dotenv - Load .env files into process.env
- env-cmd - Execute commands with .env variables
- cross-env - Cross-platform environment variable setting
- envalid - Environment variable validation
- dotenv-safe - Enforce .env.example structure
- 🐛 Report bugs
- 💡 Request features
- 📧 Email: support@muin.company
- 💬 Community Discord (coming soon)
Made with ❤️ by muin
Stop maintaining .env.example by hand. Automate it.