envkeeper
v2.2.0
Published
π‘οΈ The most human-friendly environment variable validator for Node.js - Beautiful error messages with actionable suggestions that actually help you fix issues
Downloads
26
Maintainers
Readme
π‘οΈ EnvKeeper
The most human-friendly environment variable validator for Node.js
Stop struggling with cryptic environment variable errors! EnvKeeper provides beautiful, actionable error messages that actually help you fix issues. No more guessing what went wrong - get clear guidance on exactly what needs to be fixed.
β¨ Why EnvKeeper is Different
π¨ Beautiful, Human-Friendly Error Messages
Unlike other validators that give you plain text errors, EnvKeeper provides:
- Colorful, formatted output that's easy to read
- Actionable suggestions that tell you exactly what to do
- Smart examples based on your variable names
- Context-aware guidance for common mistakes
Example Error Output:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Environment Variable Error
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π¨ Required environment variables are not set!
Your application needs these variables to run properly.
Missing Variables:
β’ DATABASE_URL
β’ API_KEY
π‘ Suggestions:
β Create a .env file in your project root if it doesn't exist
β Add the following variables to your .env file:
DATABASE_URL=your_value_here
API_KEY=your_value_here
β Make sure your .env file is in the project root directory
β Example: DATABASE_URL=postgresql://user:pass@localhost:5432/db
β Example: API_KEY=your_secret_key_here
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
βΉοΈ Need help? Check the documentation:
https://github.com/anandanpm/env-guard#readme
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββπ Quick Start
Installation
npm install envkeeperBasic Usage
const envKeeper = require('envkeeper');
// At the top of your app entry point (index.js, app.js, etc.)
// Require critical environment variables - app won't start without them
envKeeper.require(['DATABASE_URL', 'API_KEY', 'JWT_SECRET']);
// Validate with type checking
envKeeper.validate({
PORT: 'port', // Must be a valid port number (1-65535)
API_URL: 'url', // Must be a valid URL
ADMIN_EMAIL: 'email', // Must be a valid email
DEBUG: 'boolean' // Must be true/false/1/0
});
// Get variable with default value
const port = envKeeper.get('PORT', 3000);
const environment = envKeeper.get('NODE_ENV', 'development');\ud83d\udcda Complete API Documentation
require(vars: string[])
Require specific environment variables to be set. Throws an error with helpful suggestions if any are missing.
envKeeper.require(['DATABASE_URL', 'API_KEY']);When to use: At application startup for critical variables your app can't run without.
validate(schema: Object)
Validate environment variables with comprehensive type checking and rules.
envKeeper.validate({
// Simple type validation
PORT: 'port',
API_URL: 'url',
ADMIN_EMAIL: 'email',
DEBUG: 'boolean',
TIMEOUT: 'number',
CONFIG: 'json',
// Advanced validation with rules
API_KEY: {
type: 'string',
minLength: 32,
maxLength: 64
},
NODE_ENV: {
enum: ['development', 'staging', 'production']
},
VERSION: {
pattern: '^\\d+\\.\\d+\\.\\d+$' // Semantic versioning
}
});Supported Types:
string- Any string valuenumber- Numeric value (e.g., "42", "3.14")boolean- true/false/1/0url- Valid URL (e.g., "https://example.com")email- Valid email addressjson- Valid JSON stringport- Valid port number (1-65535)
Validation Rules:
type- Data type validationminLength- Minimum string lengthmaxLength- Maximum string lengthpattern- Regular expression patternenum- List of allowed values
get(varName: string, defaultValue?: any, validation?: string | Object)
Get an environment variable with optional default value and validation.
// Simple get with default
const port = envKeeper.get('PORT', 3000);
// Get with validation
const apiKey = envKeeper.get('API_KEY', null, {
type: 'string',
minLength: 20
});
// Throws error if variable is missing and no default provided
const requiredVar = envKeeper.get('REQUIRED_VAR');When to use: When you want a single variable with a fallback value, or when you want to validate inline.
check(vars: string[])
Check if variables are set without throwing an error. Returns a status object.
const status = envKeeper.check(['DATABASE_URL', 'API_KEY', 'OPTIONAL_VAR']);
console.log(status);
// {
// valid: false,
// missing: ['API_KEY'],
// set: ['DATABASE_URL', 'OPTIONAL_VAR']
// }
if (!status.valid) {
console.warn(`Missing variables: ${status.missing.join(', ')}`);
}When to use: For optional variables or when you want to handle missing variables gracefully without throwing.
printStatus(vars: string[])
Print a beautiful formatted status of environment variables (useful for debugging).
envKeeper.printStatus(['DATABASE_URL', 'API_KEY', 'DEBUG', 'OPTIONAL_VAR']);Output:
Environment Variables Status:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DATABASE_URL: SET
β API_KEY: SET
β DEBUG: SET
β OPTIONAL_VAR: MISSING
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββlist(hideValues?: boolean)
List all environment variables (useful for debugging, values hidden by default for security).
const allVars = envKeeper.list(); // Values hidden
const allVarsVisible = envKeeper.list(false); // Values visibleaddCustomValidator(typeName, validator, errorMessage?)
Add your own custom validation types for specific business needs.
// Simple custom validator
envKeeper.addCustomValidator(
'phone',
(value) => /^\d{10}$/.test(value),
'"{value}" is not a valid 10-digit phone number. Example: 1234567890'
);
// Use it like built-in types
envKeeper.validate({ PHONE_NUMBER: 'phone' });addCustomValidators(validators)
Register multiple custom validators at once.
envKeeper.addCustomValidators({
phone: {
validate: (value) => /^\d{10}$/.test(value),
errorMessage: 'Must be 10 digits'
},
zipcode: {
validate: (value) => /^\d{5}$/.test(value),
errorMessage: 'Must be 5 digits'
},
ipv4: (value) => {
const parts = value.split('.');
return parts.length === 4 && parts.every(p => {
const num = parseInt(p);
return num >= 0 && num <= 255;
});
}
});Common Custom Validator Examples:
// AWS Region validator
envKeeper.addCustomValidator('awsregion', (value) => {
const regions = ['us-east-1', 'us-west-1', 'eu-west-1'];
return regions.includes(value);
});
// Strong password validator
envKeeper.addCustomValidator('strongpassword', (value) => {
return value.length >= 8 &&
/[A-Z]/.test(value) &&
/[a-z]/.test(value) &&
/[0-9]/.test(value) &&
/[!@#$%^&*]/.test(value);
});
// Hex color validator
envKeeper.addCustomValidator('hexcolor',
(value) => /^#[0-9A-Fa-f]{6}$/.test(value)
);
// Slug validator (URL-friendly)
envKeeper.addCustomValidator('slug',
(value) => /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value)
);removeCustomValidator(typeName)
Remove a custom validator.
envKeeper.removeCustomValidator('phone');getCustomValidators()
Get list of all registered custom validators.
const customTypes = envKeeper.getCustomValidators();
console.log('Custom types:', customTypes); // ['phone', 'zipcode', 'ipv4']π― Real-World Examples
Express.js Application
const express = require('express');
const envKeeper = require('envkeeper');
// Validate environment at startup
try {
envKeeper.validate({
PORT: 'port',
DATABASE_URL: 'url',
JWT_SECRET: { type: 'string', minLength: 32 },
NODE_ENV: { enum: ['development', 'production', 'test'] },
SMTP_HOST: 'string',
SMTP_PORT: 'port',
ADMIN_EMAIL: 'email'
});
console.log('\u2705 Environment variables validated successfully!');
} catch (error) {
console.error(error.toString());
process.exit(1);
}
const app = express();
const port = envKeeper.get('PORT', 3000);
// Your app code...
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});Microservice Configuration
const envKeeper = require('envkeeper');
// Required variables that must exist
envKeeper.require([
'SERVICE_NAME',
'DATABASE_URL',
'REDIS_URL',
'API_KEY'
]);
// Validate all configurations
envKeeper.validate({
PORT: 'port',
DATABASE_URL: 'url',
REDIS_URL: 'url',
MAX_CONNECTIONS: 'number',
ENABLE_CACHE: 'boolean',
LOG_LEVEL: { enum: ['debug', 'info', 'warn', 'error'] }
});
// Use the values
const config = {
port: envKeeper.get('PORT', 8080),
database: process.env.DATABASE_URL,
redis: process.env.REDIS_URL,
maxConnections: Number(envKeeper.get('MAX_CONNECTIONS', 10)),
enableCache: process.env.ENABLE_CACHE === 'true'
};
module.exports = config;Docker & CI/CD
const envKeeper = require('envkeeper');
// Check optional CI/CD specific variables
const ciStatus = envKeeper.check([
'CI',
'GITHUB_ACTIONS',
'DOCKER_BUILD'
]);
if (ciStatus.valid) {
console.log('Running in CI/CD environment');
}
// Required for deployment
if (process.env.NODE_ENV === 'production') {
envKeeper.validate({
DATABASE_URL: 'url',
API_KEY: { type: 'string', minLength: 32 },
ALLOWED_ORIGINS: 'string',
SENTRY_DSN: 'url'
});
}\ud83c\udd9a\ufe0f EnvKeeper vs Others
EnvKeeper vs dotenv
| Feature | EnvKeeper | dotenv | |---------|-----------|--------| | Load .env files | β (use dotenv first) | β | | Validation | β Comprehensive | β None | | Type checking | β 7+ types | β None | | Error messages | β Beautiful & actionable | N/A | | Fail fast | β At startup | β Runtime failures | | Smart suggestions | β Context-aware | β None |
Use together:
require('dotenv').config(); // Load .env file
const envKeeper = require('envkeeper');
envKeeper.require(['DATABASE_URL', 'API_KEY']); // ValidateEnvKeeper vs envalid
| Feature | EnvKeeper | envalid |
|---------|-----------|---------|
| Error messages | β
Colorful & formatted | β Plain text |
| Suggestions | β
Actionable guidance | β Basic errors |
| Learning curve | β
Simple API | β οΈ More complex |
| Zero dependencies | β
| β
|
| TypeScript | β
| β
|
| Status display | β
printStatus() | β |
EnvKeeper vs env-var
| Feature | EnvKeeper | env-var | |---------|-----------|---------| | Batch validation | β Validate many at once | β οΈ One by one | | Error formatting | β Beautiful output | β Basic | | Suggestions | β Smart hints | β None | | Pattern matching | β Regex support | β | | Enum validation | β | β |
\ud83e\udde0 Smart Error Messages
EnvKeeper analyzes your variable names and provides relevant examples:
// Missing PORT variable
envKeeper.require(['PORT']);
// Suggestion includes: "Example: PORT=3000"
// Missing DATABASE_URL
envKeeper.require(['DATABASE_URL']);
// Suggestion includes: "Example: DATABASE_URL=postgresql://user:pass@localhost:5432/db"
// Missing API_KEY
envKeeper.require(['API_KEY']);
// Suggestion includes: "Example: API_KEY=your_secret_key_here"
// Invalid port number
envKeeper.validate({ PORT: 'port' });
// Error: "abc" is not a valid port number (1-65535). Example: 3000
// Invalid URL
envKeeper.validate({ API_URL: 'url' });
// Error: "not-a-url" is not a valid URL. Example: https://example.com\ud83d\udee0\ufe0f Best Practices
1. Validate at Application Startup
// index.js or app.js
require('dotenv').config();
const envKeeper = require('envkeeper');
// Fail fast - validate before anything else
envKeeper.validate({
DATABASE_URL: 'url',
API_KEY: { type: 'string', minLength: 32 },
PORT: 'port'
});
// Rest of your application code...2. Use require() for Critical Variables
// These variables are absolutely required
envKeeper.require(['DATABASE_URL', 'JWT_SECRET', 'API_KEY']);
// Optional variables can use get() with defaults
const logLevel = envKeeper.get('LOG_LEVEL', 'info');3. Combine with dotenv
// Load .env file first
require('dotenv').config();
// Then validate
const envKeeper = require('envkeeper');
envKeeper.validate({ /* your schema */ });4. Different Validation for Different Environments
const envKeeper = require('envkeeper');
// Base configuration (all environments)
envKeeper.require(['NODE_ENV', 'PORT']);
// Production-specific
if (process.env.NODE_ENV === 'production') {
envKeeper.validate({
DATABASE_URL: 'url',
REDIS_URL: 'url',
API_KEY: { type: 'string', minLength: 32 },
SENTRY_DSN: 'url'
});
}
// Development-specific
if (process.env.NODE_ENV === 'development') {
envKeeper.validate({
DATABASE_URL: 'url',
DEBUG: 'boolean'
});
}5. Use printStatus() for Debugging
if (process.env.DEBUG === 'true') {
envKeeper.printStatus([
'DATABASE_URL',
'API_KEY',
'REDIS_URL',
'SMTP_HOST'
]);
}\ud83d\udcdd Example .env File
# Server Configuration
PORT=3000
NODE_ENV=development
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/myapp
# Redis
REDIS_URL=redis://localhost:6379
# API Keys
API_KEY=your_secret_api_key_here_min_32_chars
JWT_SECRET=your_jwt_secret_here_at_least_32_characters
# Email Configuration
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
[email protected]
SMTP_PASS=your-password
[email protected]
# Feature Flags
ENABLE_CACHE=true
DEBUG=false
LOG_LEVEL=info
# External Services
STRIPE_SECRET_KEY=sk_test_your_stripe_key
SENTRY_DSN=https://[email protected]/project
# Allowed Values
ENVIRONMENT=development
# Valid: development, staging, production\ud83d\udc1b Error Handling
Catching Errors
const envKeeper = require('envkeeper');
try {
envKeeper.validate({
PORT: 'port',
API_URL: 'url'
});
} catch (error) {
if (error.name === 'EnvKeeperError') {
// Access error details
console.log('Missing:', error.missing);
console.log('Invalid:', error.invalid);
console.log('Suggestions:', error.suggestions);
// Print formatted message
console.error(error.toString());
// Exit or handle gracefully
process.exit(1);
}
}Custom Error Handling
const envKeeper = require('envkeeper');
function validateEnvironment() {
try {
envKeeper.validate({
DATABASE_URL: 'url',
API_KEY: { type: 'string', minLength: 32 }
});
return { success: true };
} catch (error) {
if (error.name === 'EnvKeeperError') {
return {
success: false,
missing: error.missing,
invalid: error.invalid,
message: error.message
};
}
throw error;
}
}
const result = validateEnvironment();
if (!result.success) {
console.error('Environment validation failed');
console.error('Missing:', result.missing);
console.error('Invalid:', result.invalid);
// Send to monitoring service, log, etc.
}\ud83d\udcbb TypeScript Support
EnvKeeper includes full TypeScript definitions:
import envKeeper, { EnvKeeper, EnvKeeperError, ValidationRule } from 'envkeeper';
// Type-safe validation
const schema: Record<string, string | ValidationRule> = {
PORT: 'port',
API_URL: 'url',
API_KEY: {
type: 'string',
minLength: 32
}
};
try {
envKeeper.validate(schema);
} catch (error) {
if (error instanceof EnvKeeperError) {
console.error(error.missing);
console.error(error.invalid);
console.error(error.suggestions);
}
}\ud83e\udd14 FAQ
Q: Do I still need dotenv?\nA: Yes! EnvKeeper validates environment variables but doesn't load .env files. Use dotenv to load files, then envKeeper to validate.
Q: Will this slow down my application?\nA: No! EnvKeeper validates once at startup. The overhead is negligible (milliseconds) and prevents costly runtime errors.
Q: Can I use this in production?\nA: Absolutely! EnvKeeper is designed for production use. It helps catch configuration issues before they cause outages.
Q: What if I have a lot of environment variables?\nA: EnvKeeper handles validation for any number of variables efficiently. The formatted errors make it easy to fix multiple issues at once.
Q: Can I disable colored output?\nA: Yes! Colors are automatically disabled when output is piped or in non-TTY environments (like CI/CD logs).
Q: How do I validate nested JSON in environment variables?\nA: Use the 'json' type:
envKeeper.validate({ CONFIG: 'json' });
const config = JSON.parse(process.env.CONFIG);\ud83d\udcdd License
MIT Β© Anandakrishnan PM
\ud83d\udc96 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
\u2b50 Star History
If you find EnvKeeper helpful, please consider giving it a star on GitHub!
\ud83d\udce6 Links
Made with \u2764\ufe0f for developers who deserve better error messages
