← Back to Blog
Code Snippets July 8, 2026

Type-Safe Environment Variable Loader (JavaScript)

💻 CODE SNIPPET — July 8, 2026

Type-Safe Environment Variable Loader (JavaScript)

Stop using \process.env.X || "fallback"\ everywhere. Define a schema with types, defaults, and validation — fail fast at startup.

\\\js
class EnvConfig {
constructor(schema) {
this.errors = [];
for (const [k, r] of Object.entries(schema)) {
let v = process.env[k];
if (!v && r.required) { this.errors.push(
❌ Missing: ${k}); continue; }
if (v === undefined) { this[k] = r.default; continue; }
if (r.type === 'number') this[k] = Number(v);
else if (r.type === 'boolean') this[k] = v.toLowerCase() === 'true';
else if (r.type === 'array') this[k] = v.split(r.sep || ',');
else if (r.type === 'enum') { if (!r.values.includes(v)) this.errors.push(
❌ ${k}: bad value); else this[k] = v; }
else this[k] = v;
if (r.type === 'number' && !isNaN(this[k])) {
if (r.min !== undefined && this[k] < r.min) this.errors.push(
❌ ${k} too low);
if (r.max !== undefined && this[k] > r.max) this.errors.push(
❌ ${k} too high);
}
}
if (this.errors.length) throw new Error(this.errors.join('\n'));
}
}

// Usage — fails at startup if anything's wrong:
const cfg = new EnvConfig({
PORT: { type: 'number', required: true, min: 1, max: 65535 },
LOG_LEVEL: { type: 'enum', required: false, values: ['debug','info','warn','error'] },
REDIS_URL: { type: 'array', required: false, sep: ',', default: ['localhost'] },
DEBUG: { type: 'boolean',required: false, default: false },
API_KEY: { type: 'string', required: true },
});
\
\\

💡 Pro Tip: Add a \.secret\ flag to sensitive vars to auto-redact them in logs.
✅ Fails fast at startup — no silent null bugs in production.