npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@opensourcesforge/envguard

v1.1.1

Published

Type-safe environment variable validation with superior TypeScript inference, zero dependencies, and advanced features like secret masking, nested objects, and .env.example generation

Downloads

301

Readme

EnvGuard

Type-safe environment variable validation for Node.js, Bun, and other JavaScript runtimes.

npm version License: MIT

Features

  • Type-safe: Full TypeScript support with automatic type inference
  • Zero dependencies: Lightweight with no external dependencies
  • Comprehensive validators: Built-in validators for strings, numbers, booleans, emails, URLs, UUIDs, durations, byte sizes, and more
  • Custom validators: Easy to create your own validators
  • Secret masking: Automatically mask sensitive values in error messages
  • Flexible defaults: Support for default, devDefault, and testDefault values
  • Conditional requirements: Make variables required based on other values
  • Warning mode: Non-blocking validation for optional variables
  • Extra variable detection: Warn or error on unknown environment variables
  • Immutable output: Validated environment is frozen and protected
  • .env.example generation: Auto-generate example files from your schema
  • Colored error output: Beautiful, readable error messages

Installation

npm install envguard

Quick Start

import { cleanEnv, str, num, bool, email, url } from 'envguard';

const env = cleanEnv({
  PORT: num({ default: 3000 }),
  HOST: str({ default: 'localhost' }),
  DATABASE_URL: url(),
  API_KEY: str({ secret: true }),
  DEBUG: bool({ default: false }),
  ADMIN_EMAIL: email({ default: '[email protected]' }),
});

// Fully typed!
console.log(env.PORT);        // number
console.log(env.HOST);        // string
console.log(env.DATABASE_URL); // string
console.log(env.DEBUG);       // boolean

// Environment helpers
console.log(env.isProduction);  // boolean
console.log(env.isDevelopment); // boolean
console.log(env.isTest);        // boolean

Validators

Basic Validators

str(options?)

Validates string values.

import { str } from 'envguard';

const env = cleanEnv({
  // Basic string
  NAME: str(),
  
  // With default
  HOST: str({ default: 'localhost' }),
  
  // With validation
  CODE: str({ 
    minLength: 3,
    maxLength: 10,
    pattern: /^[A-Z]+$/,
  }),
  
  // With transformation
  SLUG: str({ 
    trim: true,
    toLowerCase: true,
  }),
  
  // With choices
  NODE_ENV: str({ 
    choices: ['development', 'staging', 'production'],
  }),
});

num(options?)

Validates numeric values.

import { num } from 'envguard';

const env = cleanEnv({
  PORT: num({ default: 3000 }),
  
  // With constraints
  MAX_CONNECTIONS: num({ 
    min: 1,
    max: 100,
    integer: true,
  }),
  
  // With choices
  RETRY_COUNT: num({ 
    choices: [1, 3, 5, 10],
  }),
});

bool(options?)

Validates boolean values. Accepts: 1, 0, true, false, yes, no, on, off, t, f, y, n.

import { bool } from 'envguard';

const env = cleanEnv({
  DEBUG: bool({ default: false }),
  ENABLE_CACHE: bool({ default: true }),
});

Network Validators

email(options?)

Validates email addresses.

import { email } from 'envguard';

const env = cleanEnv({
  ADMIN_EMAIL: email(),
  SUPPORT_EMAIL: email({ default: '[email protected]' }),
});

url(options?)

Validates URLs with http/https protocol.

import { url } from 'envguard';

const env = cleanEnv({
  API_URL: url(),
  WEBHOOK_URL: url({ default: 'https://example.com/webhook' }),
});

host(options?)

Validates hostnames or IP addresses (IPv4 and IPv6).

import { host } from 'envguard';

const env = cleanEnv({
  DB_HOST: host({ default: 'localhost' }),
  REDIS_HOST: host(),
});

port(options?)

Validates TCP port numbers (1-65535).

import { port } from 'envguard';

const env = cleanEnv({
  PORT: port({ default: 3000 }),
  
  // Custom range
  ADMIN_PORT: port({ min: 1024, max: 49151 }),
});

Data Validators

json<T>(options?)

Parses JSON values.

import { json } from 'envguard';

const env = cleanEnv({
  CONFIG: json<{ key: string }>(),
  
  // With schema validation
  SETTINGS: json<Settings>({
    schema: (v): v is Settings => 
      typeof v === 'object' && v !== null && 'name' in v,
  }),
});

array<T>(options?)

Parses comma-separated values into arrays.

import { array, num } from 'envguard';

const env = cleanEnv({
  // String array
  ALLOWED_HOSTS: array({ default: ['localhost'] }),
  
  // Custom separator
  TAGS: array({ separator: '|' }),
  
  // With item validation
  PORTS: array({ itemValidator: num() }),
  
  // With constraints
  IDS: array({ 
    minItems: 1,
    maxItems: 10,
    unique: true,
  }),
});

uuid(options?)

Validates UUID strings.

import { uuid } from 'envguard';

const env = cleanEnv({
  SESSION_ID: uuid(),
  TENANT_ID: uuid({ default: '00000000-0000-0000-0000-000000000000' }),
});

Special Validators

enums(options)

Validates against a list of allowed values with proper TypeScript inference.

import { enums } from 'envguard';

const env = cleanEnv({
  LOG_LEVEL: enums({ 
    values: ['debug', 'info', 'warn', 'error'] as const,
    default: 'info',
  }),
});

// env.LOG_LEVEL is typed as 'debug' | 'info' | 'warn' | 'error'

regex(options)

Validates against a custom regular expression.

import { regex } from 'envguard';

const env = cleanEnv({
  LICENSE_KEY: regex({ 
    pattern: /^[A-Z]{3}-\d{4}-[A-Z]{3}$/,
    desc: 'License key in format XXX-0000-XXX',
  }),
});

duration(options?)

Parses duration strings (e.g., 100ms, 5s, 2m, 1h, 7d).

import { duration } from 'envguard';

const env = cleanEnv({
  // Returns milliseconds by default
  TIMEOUT: duration({ default: 5000 }),
  
  // Convert to seconds
  CACHE_TTL: duration({ unit: 's' }),
});

// TIMEOUT=30s -> 30000 (ms)
// CACHE_TTL=5m -> 300 (s)

bytes(options?)

Parses byte size strings (e.g., 100B, 5KB, 2MB, 1GB).

import { bytes } from 'envguard';

const env = cleanEnv({
  // Returns bytes by default
  MAX_FILE_SIZE: bytes({ default: 10485760 }), // 10MB
  
  // Convert to megabytes
  MEMORY_LIMIT: bytes({ unit: 'MB' }),
});

// MAX_FILE_SIZE=50MB -> 52428800 (bytes)
// MEMORY_LIMIT=2GB -> 2048 (MB)

Advanced Features

Default Values

EnvGuard supports multiple types of default values:

const env = cleanEnv({
  // Always use this default
  PORT: num({ default: 3000 }),
  
  // Only in non-production environments
  DEBUG: bool({ devDefault: true }),
  
  // Only in test environment
  DB_URL: str({ testDefault: 'sqlite::memory:' }),
});

Secret Masking

Mark sensitive variables to mask their values in error messages:

const env = cleanEnv({
  API_KEY: str({ secret: true }),
  DATABASE_PASSWORD: str({ secret: true }),
});

// Error messages will show: "API_KEY: supe**********d123"

Conditional Requirements

Make variables required based on other values:

const env = cleanEnv({
  USE_REDIS: bool({ default: false }),
  REDIS_URL: str({
    requiredWhen: (env) => env.USE_REDIS === true,
    default: undefined,
  }),
});

Warning Mode

Use warnOnly for non-critical variables that shouldn't block startup:

const env = cleanEnv({
  ANALYTICS_KEY: str({ 
    warnOnly: true,
    desc: 'Optional analytics tracking key',
  }),
});

Extra Variable Detection

Detect unknown environment variables:

const env = cleanEnv(
  { PORT: num() },
  {
    // Warn about extra variables
    warnOnExtra: true,
    
    // Or throw an error
    strict: true,
    
    // Allow specific extra variables
    allowedExtra: ['CUSTOM_VAR'],
  }
);

Custom Validators

Create your own validators:

import { makeValidator, EnvValidationError } from 'envguard';

const hexColor = makeValidator<string>((value, key) => {
  if (!/^#[0-9A-Fa-f]{6}$/.test(value)) {
    throw new EnvValidationError(key, 'must be a valid hex color', value);
  }
  return value.toLowerCase();
});

const env = cleanEnv({
  PRIMARY_COLOR: hexColor({ default: '#000000' }),
  ACCENT_COLOR: hexColor(),
});

Custom Middleware

Transform the validated environment:

import { customCleanEnv, str, num } from 'envguard';

const env = customCleanEnv(
  {
    DB_HOST: str({ default: 'localhost' }),
    DB_PORT: num({ default: 5432 }),
    DB_NAME: str(),
  },
  (env) => ({
    ...env,
    connectionString: `postgres://${env.DB_HOST}:${env.DB_PORT}/${env.DB_NAME}`,
  })
);

console.log(env.connectionString);

Utility Functions

Group by Prefix

import { cleanEnv, str, num, groupByPrefix } from 'envguard';

const env = cleanEnv({
  DB_HOST: str({ default: 'localhost' }),
  DB_PORT: num({ default: 5432 }),
  DB_NAME: str({ default: 'mydb' }),
  CACHE_HOST: str({ default: 'localhost' }),
});

const dbConfig = groupByPrefix(env, 'DB');
// { host: 'localhost', port: 5432, name: 'mydb' }

Generate .env.example

import { writeEnvExample, str, num, bool } from 'envguard';

const spec = {
  PORT: num({ default: 3000, desc: 'Server port' }),
  HOST: str({ desc: 'Server host', example: 'localhost' }),
  DEBUG: bool({ default: false, desc: 'Enable debug mode' }),
  API_KEY: str({ desc: 'API key for external service', secret: true }),
};

writeEnvExample(spec, {
  outputPath: '.env.example',
  includeDescriptions: true,
  includeExamples: true,
  groupByPrefix: true,
});

Output:

# Server port
PORT=3000
# Server host
HOST=localhost
# Enable debug mode
DEBUG=false
# API key for external service
API_KEY= # Required

Custom Reporter

Override error handling:

import { cleanEnv, str } from 'envguard';

const env = cleanEnv(
  { API_KEY: str() },
  {
    reporter: {
      onError: (errors) => {
        // Custom error handling
        console.error('Config errors:', errors);
        process.exit(1);
      },
      onWarning: (warnings) => {
        // Custom warning handling
        console.warn('Config warnings:', warnings);
      },
    },
  }
);

API Reference

cleanEnv(spec, options?)

Main validation function.

Options:

  • env: Custom environment object (default: process.env)
  • reporter: Custom error reporter
  • strict: Throw on unknown variables (default: false)
  • warnOnExtra: Warn on unknown variables (default: false)
  • allowedExtra: Array of allowed extra variable names

Validator Options

All validators accept these common options:

  • default: Default value when variable is missing
  • devDefault: Default for non-production environments
  • testDefault: Default for test environment only
  • choices: Array of allowed values
  • desc: Description for documentation
  • example: Example value for .env.example
  • docs: URL to documentation
  • secret: Mask value in error messages
  • deprecated: Deprecation warning message
  • requiredWhen: Function to determine if required
  • warnOnly: Don't fail on validation errors

License

MIT