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

@hedystia/env

v1.1.1

Published

A powerful, type-safe environment variable parser and validator for Node.js and Bun applications.

Readme

@hedystia/env

A powerful, type-safe environment variable parser and validator for Node.js and Bun applications.

Features

  • 🔒 Type-safe - Full TypeScript support with extensive type definitions
  • Validation - 50+ built-in validators for common data types
  • 🎯 Zero dependencies - Lightweight and fast
  • 🔄 Flexible - Support for default values and custom parsers
  • 🚀 Runtime agnostic - Works with both Node.js and Bun
  • 📝 Well documented - Comprehensive JSDoc comments for all functions

Installation

npm install @hedystia/env
pnpm add @hedystia/env
yarn add @hedystia/env
bun add @hedystia/env

Quick Start

import { getEnv, portEnv, booleanEnv, stringEnv } from '@hedystia/env';

const PORT = getEnv({
  variable: 'PORT',
  type: portEnv,
  defaultValue: 3000
});

const DEBUG = getEnv({
  variable: 'DEBUG',
  type: booleanEnv,
  defaultValue: false
});

const API_KEY = getEnv({
  variable: 'API_KEY',
  type: stringEnv
});

Available Validators

Basic Types

| Validator | Description | Example | |-----------|-------------|---------| | stringEnv | Plain string without transformation | APP_NAME=MyApp | | numberEnv | Any numeric value | TIMEOUT=5000 | | intEnv | Integer values only | MAX_CONNECTIONS=100 | | floatEnv | Floating-point numbers | PRICE=19.99 | | booleanEnv | Boolean values (true/false/1/0/yes/no) | DEBUG=true |

Numeric Validators

| Validator | Description | Example | |-----------|-------------|---------| | positiveEnv | Positive numbers only (> 0) | WORKERS=4 | | nonNegativeEnv | Non-negative numbers (>= 0) | RETRY_COUNT=0 | | negativeEnv | Negative numbers only (< 0) | OFFSET=-10 | | rangeEnv(min, max) | Numbers within range | PERCENTAGE=75 | | percentageEnv | Values between 0-100 | CACHE_HIT_RATE=85 | | portEnv | Valid port numbers (0-65535) | PORT=3000 | | timestampEnv | Unix timestamps | SESSION_START=1234567890 |

String Validators

| Validator | Description | Example | |-----------|-------------|---------| | nonEmptyEnv | Non-empty strings | APP_NAME=MyApp | | trimmedEnv | No leading/trailing whitespace | API_KEY=abc123 | | alphaEnv | Only alphabetic characters | COUNTRY=USA | | alphanumericEnv | Only letters and numbers | TOKEN=abc123 | | lowercaseEnv | Only lowercase characters | DB_NAME=mydb | | uppercaseEnv | Only uppercase characters | REGION=US-EAST | | minLengthEnv(n) | Minimum string length | PASSWORD=secret123 | | maxLengthEnv(n) | Maximum string length | USERNAME=john | | lengthEnv(n) | Exact string length | ZIP_CODE=12345 | | regexEnv(pattern) | Custom regex validation | API_KEY=... |

Network & Web

| Validator | Description | Example | |-----------|-------------|---------| | urlEnv | Valid URL objects | API_URL=https://api.example.com | | emailEnv | Email addresses | [email protected] | | ipv4Env | IPv4 addresses | HOST_IP=192.168.1.1 | | ipv6Env | IPv6 addresses | HOST_IPV6=::1 | | hostnameEnv | Valid hostnames | HOSTNAME=example.com | | domainEnv | Domain names | DOMAIN=example.com | | slugEnv | URL slugs | ARTICLE_SLUG=my-article | | phoneEnv | Phone numbers | CONTACT_PHONE=+1234567890 |

Database & Services

| Validator | Description | Example | |-----------|-------------|---------| | mongoUriEnv | MongoDB connection strings | MONGODB_URI=mongodb://localhost | | postgresUriEnv | PostgreSQL connection strings | DATABASE_URL=postgresql://... | | redisUriEnv | Redis connection strings | REDIS_URL=redis://localhost |

Identifiers & Tokens

| Validator | Description | Example | |-----------|-------------|---------| | uuidEnv | UUID validation | SESSION_ID=123e4567-e89b-12d3-... | | jwtEnv | JWT token format | AUTH_TOKEN=eyJhbGc... | | base64Env | Base64 encoded strings | ENCRYPTED_KEY=YWJjMTIz | | hexEnv | Hexadecimal strings | SECRET_HEX=a1b2c3 | | hexColorEnv | Hex color codes | BRAND_COLOR=#FF5733 | | macAddressEnv | MAC addresses | DEVICE_MAC=00:1B:44:11:3A:B7 | | creditCardEnv | Credit card format | CARD_NUMBER=4111111111111111 |

Date & Time

| Validator | Description | Example | |-----------|-------------|---------| | dateEnv | Any parseable date | EXPIRES_AT=2024-12-31 | | isoDateEnv | ISO 8601 format dates | CREATED_AT=2024-01-01T00:00:00Z | | timestampEnv | Unix timestamps | SESSION_START=1234567890 |

Arrays

| Validator | Description | Example | |-----------|-------------|---------| | arrayEnv(separator) | String arrays | ALLOWED_ORIGINS=a.com,b.com | | numberArrayEnv(separator) | Number arrays | PORTS=3000,4000,5000 | | intArrayEnv(separator) | Integer arrays | USER_IDS=1,2,3 | | booleanArrayEnv(separator) | Boolean arrays | FLAGS=true,false,true |

Complex Types

| Validator | Description | Example | |-----------|-------------|---------| | jsonEnv | JSON objects | CONFIG={"key":"value"} | | enumEnv(...values) | Enum validation | LOG_LEVEL=info | | pathEnv | File paths | DATA_DIR=/var/data | | absolutePathEnv | Absolute paths only | LOG_PATH=/var/log/app.log | | mimeTypeEnv | MIME types | CONTENT_TYPE=application/json | | semverEnv | Semantic versions | APP_VERSION=1.2.3 | | latitudeEnv | Latitude coordinates | LOCATION_LAT=40.7128 | | longitudeEnv | Longitude coordinates | LOCATION_LNG=-74.0060 |

Usage Examples

Basic Usage

import { getEnv, stringEnv, numberEnv } from '@hedystia/env';

const appName = getEnv({
  variable: 'APP_NAME',
  type: stringEnv,
  defaultValue: 'MyApp'
});

const port = getEnv({
  variable: 'PORT',
  type: numberEnv,
  defaultValue: 3000
});

Enum Validation

import { getEnv, enumEnv } from '@hedystia/env';

const logLevel = getEnv({
  variable: 'LOG_LEVEL',
  type: enumEnv('debug', 'info', 'warn', 'error'),
  defaultValue: 'info'
});

Array Parsing

import { getEnv, arrayEnv, numberArrayEnv } from '@hedystia/env';

const allowedOrigins = getEnv({
  variable: 'ALLOWED_ORIGINS',
  type: arrayEnv(',')
});

const ports = getEnv({
  variable: 'PORTS',
  type: numberArrayEnv(',')
});

JSON Configuration

import { getEnv, jsonEnv } from '@hedystia/env';

interface Config {
  database: {
    host: string;
    port: number;
  };
}

const config = getEnv({
  variable: 'APP_CONFIG',
  type: jsonEnv<Config>
});

Range Validation

import { getEnv, rangeEnv } from '@hedystia/env';

const workers = getEnv({
  variable: 'WORKERS',
  type: rangeEnv(1, 10),
  defaultValue: 4
});

Custom Regex Validation

import { getEnv, regexEnv } from '@hedystia/env';

const apiKey = getEnv({
  variable: 'API_KEY',
  type: regexEnv(/^[A-Z0-9]{32}$/)
});

URL Parsing

import { getEnv, urlEnv } from '@hedystia/env';

const apiUrl = getEnv({
  variable: 'API_URL',
  type: urlEnv
});

console.log(apiUrl.hostname);
console.log(apiUrl.protocol);

Utility Functions

Environment Helpers

import {
  isProduction,
  isDevelopment,
  isTest,
  getEnvironment,
  hasEnv,
  requireEnv
} from '@hedystia/env';

if (isProduction()) {
  console.log('Running in production');
}

if (isDevelopment()) {
  console.log('Running in development');
}

const env = getEnvironment('development');

if (hasEnv('OPTIONAL_KEY')) {
  console.log('Optional key exists');
}

requireEnv(['DATABASE_URL', 'API_KEY', 'SECRET']);

Multiple Variables

import { getMultipleEnv, getOptionalEnv } from '@hedystia/env';

// Simple usage - returns raw strings
const [host, port, db] = getMultipleEnv(['HOST', 'PORT', 'DATABASE']);

// With type parsing
const [hostname, portNum] = getMultipleEnv([
  { variable: 'HOST' },
  { variable: 'PORT', type: portEnv }
]);

const optionalKey = getOptionalEnv('OPTIONAL_API_KEY');

// With type parsing
const optionalPort = getOptionalEnv({ variable: 'OPTIONAL_PORT', type: portEnv });

Optional Variables

import { getEnv, getOptionalEnv, portEnv } from '@hedystia/env';

// Using getOptionalEnv with simple variable name
const apiKey = getOptionalEnv('API_KEY'); // string | undefined

// Using getOptionalEnv with type parsing
const port = getOptionalEnv({ variable: 'PORT', type: portEnv }); // number | undefined

// Using getEnv with optional flag
const apiSecret = getEnv({
  variable: 'API_SECRET',
  type: stringEnv,
  optional: true // returns undefined if not set, instead of throwing
}); // string | undefined

Checking Variable Existence

import { hasEnv, portEnv } from '@hedystia/env';

// Simple check - just existence
if (hasEnv('OPTIONAL_KEY')) {
  console.log('OPTIONAL_KEY exists');
}

// Check existence with type validation
if (hasEnv({ variable: 'PORT', type: portEnv })) {
  console.log('PORT exists and is a valid port number');
}

Requiring Multiple Variables

import { requireEnv, portEnv, numberEnv } from '@hedystia/env';

// Simple requirement - just check existence
requireEnv(['DATABASE_URL', 'API_KEY']);

// With type validation
requireEnv([
  { variable: 'PORT', type: portEnv },
  { variable: 'WORKERS', type: numberEnv },
  { variable: 'DATABASE_URL' }
]);

Error Handling

All validators throw descriptive errors when validation fails:

import { getEnv, portEnv } from '@hedystia/env';

try {
  const port = getEnv({
    variable: 'PORT',
    type: portEnv
  });
} catch (error) {
  console.error(error.message);
}

Example error messages:

  • Missing environment variable "PORT"
  • Error parsing environment variable "PORT": Invalid port number: "abc"
  • Error parsing environment variable "EMAIL": Invalid email format: "notanemail"

TypeScript Support

Full TypeScript support with type inference:

import { getEnv, numberEnv, booleanEnv } from '@hedystia/env';

const port: number = getEnv({
  variable: 'PORT',
  type: numberEnv,
  defaultValue: 3000
});

const debug: boolean = getEnv({
  variable: 'DEBUG',
  type: booleanEnv,
  defaultValue: false
});

Custom Validators

Create your own validators:

import { RawValueMapper, getEnv } from '@hedystia/env';

const customValidator: RawValueMapper<string> = (rawValue: string): string => {
  if (!rawValue.startsWith('custom_')) {
    throw new Error(`Value must start with 'custom_': "${rawValue}"`);
  }
  return rawValue;
};

const value = getEnv({
  variable: 'CUSTOM_VALUE',
  type: customValidator
});

Best Practices

  1. Validate early - Load and validate all environment variables at application startup
  2. Use specific types - Use the most specific validator for your use case
  3. Provide defaults - Set sensible defaults for non-critical variables
  4. Document requirements - Clearly document required environment variables
  5. Fail fast - Let validation errors crash during startup rather than runtime

Example Configuration File

import {
  getEnv,
  stringEnv,
  portEnv,
  booleanEnv,
  enumEnv,
  urlEnv,
  requireEnv
} from '@hedystia/env';

requireEnv(['DATABASE_URL', 'API_KEY']);

export const config = {
  app: {
    name: getEnv({ variable: 'APP_NAME', type: stringEnv, defaultValue: 'MyApp' }),
    port: getEnv({ variable: 'PORT', type: portEnv, defaultValue: 3000 }),
    env: getEnv({
      variable: 'NODE_ENV',
      type: enumEnv('development', 'production', 'test'),
      defaultValue: 'development'
    })
  },
  database: {
    url: getEnv({ variable: 'DATABASE_URL', type: urlEnv })
  },
  features: {
    debug: getEnv({ variable: 'DEBUG', type: booleanEnv, defaultValue: false })
  },
  api: {
    key: getEnv({ variable: 'API_KEY', type: stringEnv })
  }
};

Runtime Support

  • ✅ Node.js 20.6.0+
  • ✅ Bun 1.2+

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Repository

GitHub Repository