Environment Variable Standard Engine Type-safe env management with validation, encryption, and auto-generation
- ๐ Type Safety - Full TypeScript support with automatic type inference
- โ Validation - Schema-based validation with detailed error messages
- ๐ Encryption - AES-256-GCM encryption for secure env files
- ๐ Auto-Generation - Automatically generate TypeScript type definitions
- ๐ฏ Zero Dependencies (runtime) - Lightweight and fast
- ๐ CLI Tools - Rich command-line interface for all operations
- ๐ง Flexible - Works with any Node.js project
npm install @thewoowon/envx
# or
yarn add @thewoowon/envx
# or
pnpm add @thewoowon/envxnpx envx initThis creates:
.env.example- Example environment fileenv.schema.ts- Schema definition fileenv.example.ts- Usage example- Updates
.gitignore
// env.schema.ts
import { defineEnv, field } from '@thewoowon/envx';
export const envSchema = defineEnv({
// Simple types
PORT: 'number',
DATABASE_URL: 'string',
ENABLE_CACHE: 'boolean',
// With configuration
NODE_ENV: field({
type: 'string',
default: 'development',
description: 'Node environment',
}),
// Optional fields
API_KEY: field({
type: 'string',
required: false,
description: 'Optional API key',
}),
});import { loadEnv } from '@thewoowon/envx';
import { envSchema } from './env.schema';
// Load and validate - throws on error
const env = loadEnv(envSchema);
// Type-safe access
console.log(env.PORT); // number
console.log(env.DATABASE_URL); // string
console.log(env.ENABLE_CACHE); // booleanInitialize envx in your project:
npx envx initValidate your environment variables:
npx envx validate
npx envx validate --schema custom.schema.ts --env .env.productionGenerate TypeScript type definitions:
npx envx generate-types
npx envx generate-types --output types/env.d.tsEncrypt your .env file:
npx envx encrypt
npx envx encrypt --input .env --output .env.encrypted
npx envx encrypt --key your-key-hereDecrypt an encrypted .env file:
npx envx decrypt --key your-key-here
npx envx decrypt --input .env.encrypted --output .env --key your-keyDefine your environment schema:
import { defineEnv } from '@thewoowon/envx';
const schema = defineEnv({
PORT: 'number',
NAME: 'string',
});Load and validate environment variables:
import { loadEnv } from '@thewoowon/envx';
const env = loadEnv(schema, {
envPath: '.env', // Path to .env file
silent: false, // Suppress warnings
strict: true, // Strict mode (default)
generateTypes: true, // Generate type definitions
typesPath: 'env.d.ts', // Output path for types
});Configure a field with options:
import { field } from '@thewoowon/envx';
const schema = defineEnv({
PORT: field({
type: 'number',
default: 3000,
required: true,
description: 'Server port number',
}),
});Programmatic encryption API:
import { EnvEncryptor } from '@thewoowon/envx';
// Generate a key
const key = EnvEncryptor.generateKey();
// Encrypt
const { key, output } = EnvEncryptor.encrypt({
input: '.env',
output: '.env.encrypted',
generateKey: true,
});
// Decrypt
const decrypted = EnvEncryptor.decrypt({
input: '.env.encrypted',
key: 'your-key',
});envx provides full type inference for your environment variables:
const schema = defineEnv({
PORT: 'number',
NAME: 'string',
DEBUG: 'boolean',
OPTIONAL: field({
type: 'string',
required: false,
}),
});
const env = loadEnv(schema);
// TypeScript knows the types!
env.PORT; // number
env.NAME; // string
env.DEBUG; // boolean
env.OPTIONAL; // string | undefined# Generate and encrypt
npx envx encrypt --generate-key
# Save the key securely (password manager, secrets vault, etc.)
# Commit .env.encrypted to version control
# DO NOT commit the key!# Team member receives .env.encrypted
# Team lead shares encryption key securely
npx envx decrypt --key <shared-key># GitHub Actions example
- name: Decrypt env
run: npx envx decrypt --key ${{ secrets.ENV_KEY }}// Before (dotenv)
import dotenv from 'dotenv';
dotenv.config();
const port = parseInt(process.env.PORT || '3000');
const dbUrl = process.env.DATABASE_URL!; // Hope it exists!
// After (envx)
import { loadEnv } from '@thewoowon/envx';
import { envSchema } from './env.schema';
const env = loadEnv(envSchema);
const port = env.PORT; // Typed as number!
const dbUrl = env.DATABASE_URL; // Guaranteed to exist!// Before (manual zod)
import { z } from 'zod';
const envSchema = z.object({
PORT: z.string().transform(Number),
DATABASE_URL: z.string(),
});
const env = envSchema.parse(process.env);
// After (envx)
import { defineEnv, loadEnv } from '@thewoowon/envx';
const schema = defineEnv({
PORT: 'number',
DATABASE_URL: 'string',
});
const env = loadEnv(schema);import { EnvValidator } from '@thewoowon/envx';
const validator = new EnvValidator(schema);
const result = validator.validate(process.env);
if (!result.success) {
console.error('Validation errors:', result.errors);
}import { EnvLoader } from '@thewoowon/envx';
const loader = new EnvLoader(schema, {
generateTypes: true,
typesPath: 'generated/env.d.ts',
});
const env = loader.load();your-project/
โโโ .env # Your actual env (gitignored)
โโโ .env.example # Example for team
โโโ .env.encrypted # Encrypted version (safe to commit)
โโโ env.schema.ts # Schema definition
โโโ env.d.ts # Auto-generated types
โโโ src/
โโโ index.ts # Use loadEnv here
Contributions are welcome! Please read our Contributing Guide first.
MIT ยฉ thewoowon
Built with:
- TypeScript
- Node.js crypto module
- Commander.js
- Chalk
Inspired by:
- dotenv
- dotenv-safe
- zod
- t3-env
- ๐ Report Bug
- ๐ก Request Feature
- ๐ Documentation
Made with โค๏ธ by thewoowon