The matrix command validates environment variables across multiple environments (development, staging, production) to catch inconsistencies before deployment.
# Auto-detect environments from .env.* files
npx env-doctor matrix
# Specify environments explicitly
npx env-doctor matrix --envs development,staging,production
Environment Variable Matrix
═══════════════════════════════════════════════════════════════════════
Variable │ development │ staging │ production │ Status
──────────────────────┼────────────────┼────────────────┼────────────────┼────────
DATABASE_URL │ ✓ localhost │ ✓ staging-db │ ✓ prod-db │ OK
REDIS_URL │ ✓ localhost │ ✓ staging │ ✓ prod │ OK
PORT │ ✓ 3000 │ ✓ 3000 │ ✓ 8080 │ OK
──────────────────────┼────────────────┼────────────────┼────────────────┼────────
STRIPE_SECRET_KEY │ ✓ sk_test_... │ ✓ sk_test_... │ ✗ MISSING │ ERROR
──────────────────────┼────────────────┼────────────────┼────────────────┼────────
DEBUG_MODE │ ✓ true │ ✓ true │ ✓ true │ WARN
Summary:
Total variables: 5
✓ Consistent: 3
✗ Errors: 1
⚠ Warnings: 1
Define environments in your config file:
// env-doctor.config.js
export default {
environments: {
development: {
envFiles: ['.env', '.env.local', '.env.development'],
description: 'Local development',
},
staging: {
envFiles: ['.env', '.env.staging'],
description: 'Staging environment',
},
production: {
envFiles: ['.env', '.env.production'],
description: 'Production environment',
strict: true, // All required vars must be present
},
},
variables: {
STRIPE_SECRET_KEY: {
required: true,
secret: true,
environments: {
development: {
pattern: /^sk_test_/,
message: 'Must use test keys in development',
},
production: {
pattern: /^sk_live_/,
message: 'Must use live keys in production',
},
},
},
DEBUG_MODE: {
type: 'boolean',
environments: {
production: {
mustBe: false,
message: 'Debug must be disabled in production',
},
},
},
},
matrix: {
requireConsistency: 'warn', // 'error' | 'warn' | 'off'
excludeFromMatrix: ['LOCAL_*', 'DEV_ONLY_*'],
},
};
Enforce different patterns per environment:
STRIPE_PUBLISHABLE_KEY: {
environments: {
development: { pattern: /^pk_test_/ },
staging: { pattern: /^pk_test_/ },
production: { pattern: /^pk_live_/ },
},
}
Require specific values in certain environments:
DEBUG_MODE: {
environments: {
production: { mustBe: false },
},
}
Make variables required only in certain environments:
SENTRY_DSN: {
required: {
development: false,
staging: true,
production: true,
},
}
Resolve issues interactively:
npx env-doctor matrix --fix
Matrix Fix Mode
═══════════════════════════════════════════════════════════
Issue 1/2: STRIPE_SECRET_KEY missing in production
development: sk_test_abc123...
staging: sk_test_def456...
production: ✗ MISSING
What would you like to do?
❯ Enter production value manually
Copy from staging
Skip for now
> Enter value: sk_live_xyz789...
✓ Added STRIPE_SECRET_KEY to .env.production
npx env-doctor matrix --format table
npx env-doctor matrix --format json
{
"environments": ["development", "staging", "production"],
"matrix": {
"DATABASE_URL": {
"development": { "status": "set", "valid": true },
"staging": { "status": "set", "valid": true },
"production": { "status": "set", "valid": true }
}
},
"summary": {
"totalVariables": 5,
"errorCount": 1,
"warningCount": 1
}
}
npx env-doctor matrix --format csv
npx env-doctor matrix --format html > report.html
Generates an interactive HTML report.
# .github/workflows/env-check.yml
name: Environment Validation
on:
push:
paths:
- '.env*'
- 'env-doctor.config.js'
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate environment matrix
run: npx env-doctor matrix --ci
- name: Upload report
if: always()
run: npx env-doctor matrix --format html > report.html
- uses: actions/upload-artifact@v4
with:
name: env-matrix-report
path: report.html
.env.development, .env.staging, .env.production