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 🙏

© 2026 – Pkg Stats / Ryan Hefner

env-exists

v1.0.0

Published

Check if environment variables exist and have values. Simple validation for required env vars.

Downloads

2

Readme

env-exists

Check if environment variables exist and have values. Simple validation for required env vars with powerful features.

Why env-exists?

Environment variable validation shouldn't be complicated:

  • Simple API: One function call to validate env vars
  • Flexible validation: Required, optional, type checking, custom rules
  • Clear error messages: Know exactly what's missing or invalid
  • TypeScript support: Full type definitions included
  • Zero dependencies: Lightweight and fast
  • Comprehensive: From basic checks to complex validation schemas

Installation

npm install env-exists

Quick Start

const envExists = require('env-exists');

// Basic validation - throws on failure
envExists(['API_KEY', 'DATABASE_URL']); // boolean or throws

// Check single variable
envExists('PORT'); // boolean or throws

// Get detailed results without throwing
const result = envExists(['API_KEY', 'PORT'], { throw: false });
console.log(result);
// {
//   valid: false,
//   missing: ['API_KEY'],
//   empty: [],
//   found: ['PORT'],
//   values: { PORT: '3000' }
// }

API Reference

envExists(vars, options?)

Main function to check if environment variables exist.

Parameters:

  • vars (string | string[]): Variable name(s) to check
  • options (object, optional): Configuration options

Options:

  • throw (boolean): Throw error on validation failure (default: true)
  • nonEmpty (boolean): Require non-empty values (default: true)
  • all (boolean): All variables must exist vs any (default: true)
  • defaults (object): Default values for missing variables
  • allowEmpty (string[]): Variables that can be empty

Returns: boolean (when throw=true) or ValidationResult object (when throw=false)

const envExists = require('env-exists');

// Basic usage - throws on failure
envExists(['API_KEY', 'DATABASE_URL']); // true or throws

// Don't throw, get details
const result = envExists(['VAR1', 'VAR2'], { throw: false });

// Allow empty values for specific vars
envExists(['API_KEY', 'DEBUG'], { allowEmpty: ['DEBUG'] });

// Provide defaults
envExists(['PORT', 'HOST'], { 
  defaults: { PORT: '3000', HOST: 'localhost' } 
});

// "Any" mode - at least one must exist
envExists(['REDIS_URL', 'MEMCACHE_URL'], { all: false });

Helper Functions

envExistsOrThrow(vars, options?)

Always throws on failure (explicit behavior).

const { envExistsOrThrow } = require('env-exists');

envExistsOrThrow(['API_KEY', 'SECRET']); // true or throws

envExistsDetails(vars, options?)

Never throws, always returns detailed results.

const { envExistsDetails } = require('env-exists');

const result = envExistsDetails(['API_KEY', 'PORT']);
console.log(result.missing); // ['API_KEY']
console.log(result.values); // { PORT: '3000' }

envExistsAll(vars, options?) / envExistsAny(vars, options?)

Explicit "all" vs "any" validation.

const { envExistsAll, envExistsAny } = require('env-exists');

envExistsAll(['VAR1', 'VAR2']); // Both must exist
envExistsAny(['VAR1', 'VAR2']); // At least one must exist

envExistsWithValues(varMap, options?)

Check for specific values.

const { envExistsWithValues } = require('env-exists');

// Exact values
envExistsWithValues({
  NODE_ENV: 'production',
  DEBUG: 'false'
});

// Multiple allowed values
envExistsWithValues({
  LOG_LEVEL: ['debug', 'info', 'warn', 'error'],
  NODE_ENV: ['development', 'production']
});

envExistsNonEmpty(vars, options?)

Explicit non-empty validation.

const { envExistsNonEmpty } = require('env-exists');

envExistsNonEmpty(['API_KEY', 'SECRET']); // Must exist and be non-empty

Advanced Functions

envGet(varName, options?)

Get single environment variable with validation and type conversion.

const { envGet } = require('env-exists');

// Basic usage
const port = envGet('PORT', { default: 3000, type: 'number' });

// Type conversion
const debug = envGet('DEBUG', { type: 'boolean', default: false });
const config = envGet('CONFIG', { type: 'json', required: false });

// Custom validation
const apiKey = envGet('API_KEY', {
  validate: /^sk-[a-zA-Z0-9]{32}$/,
  required: true
});

// Function validator
const port = envGet('PORT', {
  type: 'number',
  validate: (val) => val > 0 && val < 65536 || 'Port must be 1-65535'
});

envValidate(schema)

Validate multiple variables with detailed schema.

const { envValidate } = require('env-exists');

const config = envValidate({
  PORT: { type: 'number', default: 3000 },
  DEBUG: { type: 'boolean', default: false },
  API_KEY: { required: true, validate: /^sk-/ },
  DATABASE_URL: { required: true },
  REDIS_URL: { required: false },
  MAX_CONNECTIONS: { 
    type: 'number', 
    default: 10,
    validate: (val) => val > 0 || 'Must be positive'
  }
});

console.log(config);
// {
//   PORT: 3000,
//   DEBUG: false,
//   API_KEY: 'sk-abc123...',
//   DATABASE_URL: 'postgres://...',
//   REDIS_URL: undefined,
//   MAX_CONNECTIONS: 10
// }

Utility Functions

envLoad(filePath?, options?)

Load environment variables from .env file.

const { envLoad } = require('env-exists');

// Load from .env file
const loaded = envLoad();

// Load from custom file
const loaded = envLoad('.env.production');

// Override existing variables
const loaded = envLoad('.env', { override: true });

console.log(loaded); // { API_KEY: 'abc123', PORT: '3000' }

envSummary(vars?)

Get summary of environment variables.

const { envSummary } = require('env-exists');

// Summary of all env vars
const summary = envSummary();

// Summary of specific vars
const summary = envSummary(['API_KEY', 'PORT', 'DEBUG']);

console.log(summary);
// {
//   total: 3,
//   defined: 2,
//   empty: 0,
//   missing: 1,
//   variables: {
//     API_KEY: { status: 'missing' },
//     PORT: { status: 'defined', value: '3000', length: 4 },
//     DEBUG: { status: 'defined', value: 'true', length: 4 }
//   }
// }

envAssert(vars, message?)

Testing helper that throws AssertionError.

const { envAssert } = require('env-exists');

// In tests
envAssert(['API_KEY'], 'API_KEY is required for tests');

Usage Examples

Application Startup Validation

const envExists = require('env-exists');

function validateEnvironment() {
  try {
    // Required for all environments
    envExists(['NODE_ENV', 'PORT']);
    
    // Production requirements
    if (process.env.NODE_ENV === 'production') {
      envExists([
        'API_KEY',
        'DATABASE_URL',
        'REDIS_URL',
        'SESSION_SECRET'
      ]);
    }
    
    // Development optional
    if (process.env.NODE_ENV === 'development') {
      envExists(['DEBUG'], { defaults: { DEBUG: 'true' } });
    }
    
    console.log('✅ Environment validation passed');
  } catch (error) {
    console.error('❌ Environment validation failed:', error.message);
    process.exit(1);
  }
}

validateEnvironment();

Configuration Object Creation

const { envValidate } = require('env-exists');

const config = envValidate({
  // Server configuration
  PORT: { type: 'number', default: 3000 },
  HOST: { default: '0.0.0.0' },
  
  // Database
  DATABASE_URL: { required: true },
  DB_POOL_SIZE: { type: 'number', default: 10 },
  
  // Redis (optional)
  REDIS_URL: { required: false },
  
  // Security
  SESSION_SECRET: { 
    required: true,
    validate: (val) => val.length >= 32 || 'Session secret must be at least 32 characters'
  },
  
  // Feature flags
  ENABLE_LOGGING: { type: 'boolean', default: true },
  LOG_LEVEL: { 
    default: 'info',
    validate: (val) => ['debug', 'info', 'warn', 'error'].includes(val) || 'Invalid log level'
  },
  
  // External services
  STRIPE_KEY: { validate: /^sk_/ },
  SENDGRID_API_KEY: { validate: /^SG\./ }
});

module.exports = config;

Environment-Specific Validation

const { envExistsAny, envExistsWithValues } = require('env-exists');

// Must have at least one cache solution
envExistsAny(['REDIS_URL', 'MEMCACHE_URL'], {
  throw: true
});

// Validate environment matches expected values
envExistsWithValues({
  NODE_ENV: ['development', 'staging', 'production'],
  LOG_LEVEL: ['debug', 'info', 'warn', 'error']
});

// Database validation
if (process.env.NODE_ENV === 'production') {
  envExistsWithValues({
    DB_SSL: 'true',
    DB_SSL_REJECT_UNAUTHORIZED: 'true'
  });
}

Microservice Configuration

const { envGet, envExists } = require('env-exists');

class ServiceConfig {
  constructor() {
    // Validate required variables exist
    envExists([
      'SERVICE_NAME',
      'SERVICE_VERSION',
      'PORT'
    ]);
    
    // Parse configuration with defaults and validation
    this.serviceName = envGet('SERVICE_NAME');
    this.version = envGet('SERVICE_VERSION');
    this.port = envGet('PORT', { type: 'number', default: 3000 });
    
    // Optional configuration
    this.logLevel = envGet('LOG_LEVEL', { default: 'info' });
    this.enableMetrics = envGet('ENABLE_METRICS', { type: 'boolean', default: true });
    
    // Database configuration
    this.database = {
      url: envGet('DATABASE_URL'),
      poolSize: envGet('DB_POOL_SIZE', { type: 'number', default: 10 }),
      timeout: envGet('DB_TIMEOUT', { type: 'number', default: 30000 })
    };
    
    // External service URLs
    this.services = {
      auth: envGet('AUTH_SERVICE_URL', { validate: /^https?:\/\// }),
      payments: envGet('PAYMENT_SERVICE_URL', { required: false })
    };
  }
  
  validate() {
    // Additional business logic validation
    if (this.port < 1024 && process.getuid?.() !== 0) {
      throw new Error('Cannot bind to privileged port without root access');
    }
    
    return this;
  }
}

const config = new ServiceConfig().validate();

Testing Setup

const { envAssert, envLoad, envSummary } = require('env-exists');

describe('Environment Tests', () => {
  beforeAll(() => {
    // Load test environment
    envLoad('.env.test');
    
    // Assert required test variables
    envAssert([
      'TEST_DATABASE_URL',
      'TEST_API_KEY'
    ], 'Missing required test environment variables');
  });
  
  test('should have all required environment variables', () => {
    const summary = envSummary([
      'NODE_ENV',
      'TEST_DATABASE_URL',
      'TEST_API_KEY'
    ]);
    
    expect(summary.missing).toBe(0);
    expect(summary.defined).toBe(3);
  });
});

Docker Environment Validation

const { envExists, envGet } = require('env-exists');

// Validate Docker secrets are mounted
const secrets = [
  'DB_PASSWORD_FILE',
  'API_KEY_FILE',
  'SSL_CERT_FILE'
].map(fileVar => {
  const filePath = envGet(fileVar);
  const fs = require('fs');
  
  if (!fs.existsSync(filePath)) {
    throw new Error(`Secret file not found: ${filePath} (from ${fileVar})`);
  }
  
  return {
    var: fileVar,
    path: filePath,
    content: fs.readFileSync(filePath, 'utf8').trim()
  };
});

console.log('✅ All Docker secrets loaded successfully');

CLI Tool Configuration

#!/usr/bin/env node
const { envLoad, envExists, envSummary } = require('env-exists');

// Load environment from multiple sources
envLoad('.env');
envLoad('.env.local', { override: true });

// CLI-specific validation
try {
  envExists(['CLI_API_KEY'], {
    defaults: { CLI_API_KEY: process.env.API_KEY } // Fallback to general API key
  });
} catch (error) {
  console.error('❌ Configuration Error:');
  console.error(error.message);
  console.error('\nTo fix this:');
  console.error('  1. Set CLI_API_KEY environment variable');
  console.error('  2. Or create .env file with CLI_API_KEY=your_key');
  console.error('  3. Or set API_KEY as fallback');
  process.exit(1);
}

// Show configuration summary
if (process.argv.includes('--debug')) {
  const summary = envSummary(['CLI_API_KEY', 'DEBUG', 'LOG_LEVEL']);
  console.log('Environment Summary:', summary);
}

Error Messages

Clear, actionable error messages help debug configuration issues:

// Missing variables
// Error: Environment validation failed (all mode): Missing: API_KEY, DATABASE_URL

// Empty variables
// Error: Environment validation failed (all mode): Empty: API_KEY

// Type validation
// Error: PORT type conversion failed: PORT must be a valid number, got: abc

// Custom validation
// Error: API_KEY does not match pattern: /^sk-/

// Schema validation
// Error: Environment validation failed:
//   - Missing: DATABASE_URL
//   - PORT type conversion failed: PORT must be a valid number, got: abc
//   - API_KEY does not match pattern: /^sk-/

TypeScript Usage

import envExists, { 
  EnvExistsOptions, 
  envValidate, 
  envGet 
} from 'env-exists';

// Basic validation
const isValid: boolean = envExists(['API_KEY', 'PORT']);

// With options
const options: EnvExistsOptions = {
  throw: false,
  nonEmpty: true,
  defaults: { PORT: '3000' }
};

const result = envExists(['API_KEY'], options);

// Schema validation
const config = envValidate({
  PORT: { type: 'number', default: 3000 },
  DEBUG: { type: 'boolean', default: false }
});

// Type-safe environment variables
const port: number = envGet('PORT', { type: 'number', default: 3000 });
const debug: boolean = envGet('DEBUG', { type: 'boolean', default: false });

Best Practices

  1. Validate early: Check environment variables at application startup
  2. Use schemas: For complex apps, use envValidate() with a schema
  3. Provide defaults: Use sensible defaults for non-critical variables
  4. Clear errors: Let env-exists generate clear error messages
  5. Environment-specific: Different validation for dev/staging/production
  6. Document requirements: List required env vars in your README

Comparison with Alternatives

| Feature | env-exists | dotenv | envalid | joi | |---------|------------|---------|---------|-----| | Simple API | ✅ | ❌ | ✅ | ❌ | | Type validation | ✅ | ❌ | ✅ | ✅ | | Custom validation | ✅ | ❌ | ✅ | ✅ | | Clear errors | ✅ | ❌ | ✅ | ✅ | | Zero dependencies | ✅ | ✅ | ❌ | ❌ | | TypeScript support | ✅ | ✅ | ✅ | ✅ | | File loading | ✅ | ✅ | ❌ | ❌ |

License

MIT License. See LICENSE file for details.

Contributing

Pull requests welcome! Please ensure tests pass:

npm test