The Zero-Boilerplate & Type-Safe Environment Manager.
Envium is the modern solution for Node.js environment variable management. Unlike traditional tools like dotenv that merely load loose strings, Envium segments, validates, strictly types, and protects your application's configuration powered by SOLID principles and robust Developer Experience (DX). It also provides event-driven watch functionality and flat destructuring support for hot-reloading in development.
- π Group Segmentation: Organize logically using
[GROUP]syntax natively inside your.envfiles. - π‘οΈ Differential Security: Applies Strict Immutability (
writable: false,configurable: false) in Production and permissive Hot-Reloading (fs.watch) in Development scenarios. - π Fail-Fast Validation: Automatically checks runtime variables against a schema. The system prevents app execution if any required variable is missing or mismatched.
- πͺ Magic TypeScript Autocomplete: Inject your schema once and gain deep nested autocomplete (e.g.
env.DATABASE.PORT) powered by native TypeScript generics. Zero.d.tsboilerplate generations hiding in your root. - π Flat Destructuring: Destructure environment variables using flat keys within groups (e.g.
const { ACCESS_KEY_ID } = env.AWS;) alongside nested access, making integration with third-party libraries seamless. - βοΈ Cloud Deployments Compatible: Features a robust "Unflattening" engine that seamlessly maps flat CI/CD variables (like
DATABASE_PORT=5432from Vercel or AWS) into your groupedenv.DATABASE.PORTruntime without changing a line of code. - π οΈ Automated CLI DX: Integrated CLI automating the creation of
.env.exampleplaceholders, Markdown documentation, and validation hooks.
npm install envium
# or using pnpm
pnpm add enviumGroup your variables to keep everything perfectly organized and readable:
NODE_ENV=development
[SERVER]
PORT=3000
DEBUG=true
[DATABASE]
HOST=localhost
USER=admin
[/DATABASE] # Optional explicit closing tagYou can write your schema manually, or run `npx envium init --ts` to automatically generate your `envium.config.ts` based on your existing `.env`:
// envium.config.ts
export const schema = {
SERVER: {
PORT: { type: 'number', required: true, default: 8080 },
DEBUG: { type: 'boolean' }
},
DATABASE: {
HOST: { type: 'string', required: true },
USER: { type: 'string' }
}
} as const; // 'as const' is required for TS deep auto-completion!Import init and pass your exported schema. By default, Envium will automatically load the `.env` file from the root of your project unless configured otherwise:
import { envium } from 'envium-js';
import { schema } from './envium.config';
// Initialize the environment manager once, usually in your main entry point (e.g. app.ts)
envium.init({
schema,
// path: '.env', -> Loads natively from root by default
watch: process.env.NODE_ENV !== 'production'
});Tip
Global Singleton Pattern: You only need to call init() once. After initialization, you can simply import env anywhere else in your project. Node.js module caching ensures you always get the initialized, fully-typed proxy instance without having to pass it around!
// Any other file in your project (e.g. database.ts)
import { env } from 'envium-js';
const connection = createConnection({
host: env.DATABASE.HOST,
port: env.SERVER.PORT
});Envium supports both nested and flat destructuring for maximum flexibility and cleaner code:
import { env } from 'envium-js';
// Flat destructuring from groups
const { ENDPOINT, REGION, ACCESS_KEY_ID, SECRET_ACCESS_KEY } = env.AWS;
// Nested destructuring
const { ENDPOINT, REGION, ACCESS: { KEY: { ID: ACCESS_KEY_ID } } } = env.AWS;
// Mix and match
const REGION = env.AWS.REGION; // Nested access
const ACCESS_KEY_ID = env.AWS.ACCESS_KEY_ID; // Flat accessThis makes configuration code cleaner and more intuitive, especially for AWS SDKs and similar libraries.
Envium provides event-driven development with built-in watchers for hot-reloading in development environments. Listen to configuration changes and react dynamically:
import { env } from 'envium-js';
// 1. The Easy Way: Listen for specific keys changing (Supports partial matches!)
env.onChange(['PORT', 'SERVER'], (event) => {
console.log(`\nπ Change detected in: ${event.keys.join(', ')}`);
console.log(`Old PORT: ${event.changes['SERVER_PORT']?.old}`);
console.log(`New PORT: ${event.changes['SERVER_PORT']?.new}`);
// E.g., restart your server here
});
// 2. The Advanced Way: Listen to all changes globally
env.on('change', (event) => {
// event.keys -> Array of changed flat keys ['SERVER_PORT', 'DATABASE_HOST']
// event.changes -> Dictionary with { old, new } for each changed key
// event.data -> The fully updated environment tree
console.log('Configuration changed:', event.keys);
});
// Remove listeners when done
env.off('change');In development mode, Envium automatically watches your .env file for changes. It calculates a strict diff between the old and new states and emits change (and reload) events only if real modifications happened. This enables seamless hot-reloading without restarting your application manually, while preventing false triggers when you just hit "Save" without making edits.
Proxy Inspection: Use console.log(env) to inspect the current configuration structure with custom symbols for debugging.
In platforms like Vercel, Railway, or AWS, deploying a .env file with [GROUP] syntax isn't possible (dashboards only support flat KEY=VALUE lists).
Envium handles this perfectly behind the scenes using our advanced Unflattener!
Define your config flatly in your deployment Dashboard by concatenating the group and variable names:
SERVER_PORT=80
DATABASE_HOST=mongodb://production
Envium will detect SERVER_PORT and map it automatically casting it natively to env.SERVER.PORT. Your application codebase remains 100% identical.
The envium CLI reads your project constraints generating utilities out of the box ensuring DRY principles (Don't Repeat Yourself!):
# 1. Generate an automated configuration based on your current .env file
npx envium init
# 2. Update your config schema when .env changes
npx envium update [--dry-run]
# 3. Generate or synchronize your ENV_DOCS.md, explaining schemas, required fields, and defaults
npx envium gen-docs
# 4. Format a .env.example file, automatically omitting credential strings by default
npx envium gen-assets
# 5. Actively validate your local .env file (Ideal for automated CI/CD pipelines)
npx envium checkBuilt focusing tightly on extreme deployment constraints avoiding manual configurations.
init(options?): Initialize Envium with optional configuration. Returns the typed environment proxy.options.mode:'development'or'production'(auto-detected by default)options.envPath: Path to.envfile (default:.env)
env.on(event, listener): Listen to events like'reload'for configuration changes.env.off(event, listener?): Remove event listeners.env.emit(event, data?): Emit custom events.env.activeMode: Get current mode ('development'or'production').env.isInitialized: Check if Envium is initialized.
npx envium init: Generate initial configuration from.env.npx envium update [--dry-run]: Update schema when.envchanges.npx envium gen-docs: Generate Markdown documentation.npx envium gen-assets: Generate.env.examplefile.npx envium check: Validate.envfile against schema.