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

strongly-typed-env

v2.2.0

Published

a tiny library for strongly typed environment variables where you can specify the types in the .env file itself, no dependencies

Readme

TypeScript Environment Configuration Library

A powerful, type-safe environment configuration library for Node.js applications that automatically generates TypeScript types from your environment files.

Features

  • 🔒 Type-safe environment variables with automatic TypeScript type generation
  • 🎯 Multiple data types - STRING, NUMBER, BOOL, ARRAY, OBJ
  • 🛡️ Runtime validation with comprehensive error handling
  • 📝 Auto-generated documentation with comments and schemas
  • 🔍 Duplicate detection and environment validation
  • 🚀 Easy integration with existing Node.js projects
  • Precise type inference for objects and arrays with actual property types

Installation

npm install strongly-typed-env

Quick Start

1. Create your environment file

Create a .env file with typed environment variables:

⚠️ Warning : Make sure to use the correct data types for each variable and each variable should start and end on a single line.

# Database Configuration
STRING DATABASE_URL = "postgresql://localhost:5432/mydb"
NUMBER DATABASE_PORT = 5432
BOOL DATABASE_SSL = true

# API Configuration
STRING API_KEY = "your-secret-api-key"
NUMBER MAX_CONNECTIONS = 100
ARRAY ALLOWED_ORIGINS = ["http://localhost:3000", "https://example.com"]
OBJ REDIS_CONFIG = {"host": "localhost", "port": 6379, "retryDelayOnFailover": 100}

# Feature Flags
BOOL ENABLE_LOGGING = true
BOOL DEBUG_MODE = false

# Advanced Examples
ARRAY PORT_NUMBERS = [3000, 4000, 5000]
ARRAY MIXED_ARRAY = ["string", 42, true]
OBJ SERVER_CONFIG = {"host": "localhost","port": 8080,"ssl": true,"timeout": 30000,"features": ["auth", "logging", "metrics"]}

2. Generate TypeScript types

Add a script to your package.json:

{
  "scripts": {
    "generate-env-types": "node -e \"require('strongly-typed-env').generateTypes('.env', './src/types/env-types.ts')\""
  }
}

Run the type generation:

npm run generate-env-types

This generates a ./src/types/env-types.ts file with precise types:

/**
 * Auto-generated TypeScript types for environment variables
 * Generated from: .env
 * Generated at: 2024-01-15T10:30:00.000Z
 *
 * DO NOT EDIT THIS FILE MANUALLY
 * Run generateTypes() to regenerate when .env changes
 */

export interface EnvConfig {
  /** Type: STRING */
  DATABASE_URL: string;
  /** Type: NUMBER */
  DATABASE_PORT: number;
  /** Type: BOOL */
  DATABASE_SSL: boolean;
  /** Type: STRING */
  API_KEY: string;
  /** Type: NUMBER */
  MAX_CONNECTIONS: number;
  /** Type: ARRAY */
  ALLOWED_ORIGINS: string[];
  /** Type: OBJ */
  REDIS_CONFIG: {
    host: string;
    port: number;
    retryDelayOnFailover: number;
  };
  /** Type: BOOL */
  ENABLE_LOGGING: boolean;
  /** Type: BOOL */
  DEBUG_MODE: boolean;
  /** Type: ARRAY */
  PORT_NUMBERS: number[];
  /** Type: ARRAY */
  MIXED_ARRAY: (string | number | boolean)[];
  /** Type: OBJ */
  SERVER_CONFIG: {
    host: string;
    port: number;
    ssl: boolean;
    timeout: number;
    features: string[];
  };
}

export const envSchema = {
  DATABASE_URL: 'STRING',
  DATABASE_PORT: 'NUMBER',
  DATABASE_SSL: 'BOOL',
  API_KEY: 'STRING',
  MAX_CONNECTIONS: 'NUMBER',
  ALLOWED_ORIGINS: 'ARRAY',
  REDIS_CONFIG: 'OBJ',
  ENABLE_LOGGING: 'BOOL',
  DEBUG_MODE: 'BOOL',
  PORT_NUMBERS: 'ARRAY',
  MIXED_ARRAY: 'ARRAY',
  SERVER_CONFIG: 'OBJ',
} as const;

export type EnvKey = keyof EnvConfig;
export type EnvType = 'STRING' | 'NUMBER' | 'BOOL' | 'ARRAY' | 'OBJ';

// Utility function to get environment variable keys
export const envKeys: EnvKey[] = [
  'DATABASE_URL',
  'DATABASE_PORT',
  'DATABASE_SSL',
  'API_KEY',
  'MAX_CONNECTIONS',
  'ALLOWED_ORIGINS',
  'REDIS_CONFIG',
  'ENABLE_LOGGING',
  'DEBUG_MODE',
  'PORT_NUMBERS',
  'MIXED_ARRAY',
  'SERVER_CONFIG',
];

// Type guard to check if a key exists in the environment config
export function isEnvKey(key: string): key is EnvKey {
  return envKeys.includes(key as EnvKey);
}

3. Use in your application

import { config, validateEnv } from 'your-env-config-package';
import { EnvConfig, envSchema } from './types/env-types';

// Load and parse environment variables
const { parsedEnv } = config<EnvConfig>({
  path: '.env',
  strict: true,
});

// Validate against schema
if (validateEnv(parsedEnv, envSchema)) {
  // Now parsedEnv is fully typed as EnvConfig with precise types
  console.log(`Database URL: ${parsedEnv.DATABASE_URL}`);
  console.log(`Port: ${parsedEnv.DATABASE_PORT}`);
  console.log(`SSL enabled: ${parsedEnv.DATABASE_SSL}`);
  console.log(`Allowed origins: ${parsedEnv.ALLOWED_ORIGINS.join(', ')}`); // string[] methods available
  console.log(`Redis host: ${parsedEnv.REDIS_CONFIG.host}`); // Typed object properties
  console.log(`Redis port: ${parsedEnv.REDIS_CONFIG.port}`); // IntelliSense knows this is a number
  console.log(`Port numbers: ${parsedEnv.PORT_NUMBERS.map((p) => p * 2)}`); // number[] methods
  console.log(
    `Server features: ${parsedEnv.SERVER_CONFIG.features.length} features`,
  ); // Nested array typing
} else {
  console.error('Environment validation failed');
  process.exit(1);
}

API Reference

generateTypes(envPath?, outputPath?, options?)

Generates TypeScript types from an environment file with precise type inference for objects and arrays.

Parameters:

  • envPath (string, optional): Path to the .env file. Default: '.env'
  • outputPath (string, optional): Output path for generated types. Default: './src/types/env-types.ts'
  • options (object, optional):
    • interfaceName (string): Name of the generated interface. Default: 'EnvConfig'
    • includeComments (boolean): Include comments in generated file. Default: true
    • exportSchema (boolean): Export schema constant. Default: true

Example:

import { generateTypes } from 'your-env-config-package';

generateTypes('.env.production', './src/types/prod-env.ts', {
  interfaceName: 'ProductionEnv',
  includeComments: false,
  exportSchema: true,
});

config<T>(options?)

Parses environment variables and returns a typed object.

Parameters:

  • options (object, optional):
    • path (string): Path to environment file. Default: '.env'
    • encoding (BufferEncoding): File encoding. Default: 'utf8'
    • strict (boolean): Throw on errors vs warn. Default: false

Returns: { parsedEnv: T }

validateEnv<T>(env, schema)

Validates environment variables against a schema.

Parameters:

  • env (Record<string, EnvValue>): Environment variables to validate
  • schema (Record<string, EnvType>): Schema to validate against

Returns: boolean - Type guard that narrows env to type T

createTypedConfig<T>()

Creates a typed config function for a specific interface.

Example:

import { createTypedConfig } from 'your-env-config-package';
import { EnvConfig } from './types/env-types';

const getConfig = createTypedConfig<EnvConfig>();
const { parsedEnv } = getConfig({ strict: true });

Supported Types

| Type | TypeScript Type | Example Value | Generated Type Example | | -------- | ------------------------- | --------------------------------------------- | --------------------------------------------------------- | | STRING | string | "hello world" | string | | NUMBER | number | 42, 3.14 | number | | BOOL | boolean | true, false | boolean | | ARRAY | Precise array types | [1, 2, 3], ["a", "b"], [1, "a", true] | number[], string[], (number \| string \| boolean)[] | | OBJ | Precise object interfaces | {"name": "John", "age": 30, "active": true} | { name: string; age: number; active: boolean } |

Advanced Type Examples

Complex Objects

OBJ DATABASE_CONFIG = {
  "connections": {
    "read": {"host": "read-db", "port": 5432},
    "write": {"host": "write-db", "port": 5432}
  },
  "pool": {"min": 5, "max": 20},
  "ssl": true,
  "features": ["logging", "metrics"]
}

Generates:

DATABASE_CONFIG: {
  connections: {
    read: { host: string; port: number };
    write: { host: string; port: number };
  };
  pool: { min: number; max: number };
  ssl: boolean;
  features: string[];
}

Mixed Arrays

ARRAY API_ENDPOINTS = [
  {"path": "/users", "methods": ["GET", "POST"]},
  {"path": "/orders", "methods": ["GET", "PUT", "DELETE"]}
]

Generates:

API_ENDPOINTS: Array<{
  path: string;
  methods: string[];
}>;

Environment File Format

# Comments are supported
TYPE VARIABLE_NAME = value

# Examples:
STRING API_URL = "https://api.example.com"
NUMBER PORT = 3000
BOOL DEBUG = true
ARRAY HOSTS = ["localhost", "example.com"]
ARRAY PORTS = [3000, 4000, 5000]
ARRAY MIXED = ["string", 42, true, {"nested": "object"}]
OBJ CONFIG = {"timeout": 5000, "retries": 3, "enabled": true}
OBJ COMPLEX_CONFIG = {
  "database": {"host": "localhost", "port": 5432},
  "cache": {"ttl": 300, "enabled": true},
  "features": ["auth", "logging"]
}

Rules:

  • Variable names must match pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$
  • Strings can be quoted or unquoted
  • Arrays and objects must be valid JSON
  • Boolean values must be true or false (case-insensitive)
  • Comments start with #
  • Empty lines are ignored
  • Nested objects and arrays are fully typed

Error Handling

The library provides comprehensive error handling:

try {
  const { parsedEnv } = config<EnvConfig>({ strict: true });
} catch (error) {
  if (error.message.includes('Environment file not found')) {
    console.error('Please create a .env file');
  } else if (error.message.includes('Invalid number value')) {
    console.error('Check your numeric values in .env');
  } else {
    console.error('Environment parsing failed:', error.message);
  }
}

Development Workflow

Recommended package.json scripts:

{
  "scripts": {
    "generate-env-types": "node -e \"require('./dist/index.js').generateTypes()\"",
    "generate-env-types:dev": "node -e \"require('./dist/index.js').generateTypes('.env.development', './src/types/dev-env.ts')\"",
    "generate-env-types:prod": "node -e \"require('./dist/index.js').generateTypes('.env.production', './src/types/prod-env.ts')\"",
    "validate-env": "node -e \"const {config,validateEnv}=require('./dist/index.js');const {envSchema}=require('./src/types/env-types.js');const {parsedEnv}=config();console.log('✅ Environment valid:', validateEnv(parsedEnv,envSchema));\""
  }
}

Git hooks integration:

Add to your .husky/pre-commit or similar:

#!/bin/sh
npm run generate-env-types
git add src/types/env-types.ts

Best Practices

  1. Keep .env files out of version control (add to .gitignore)
  2. Commit generated type files for team consistency
  3. Use environment-specific files (.env.development, .env.production)
  4. Validate environment on application startup
  5. Use meaningful variable names and group related variables
  6. Document complex object/array structures in comments
  7. Leverage precise typing for better IntelliSense and runtime safety

Examples

Advanced Usage with Full Type Safety

import { config, validateEnv, createTypedConfig } from 'strongly-typed-env';
import { EnvConfig, envSchema } from './types/env-types';

// Create environment-specific configs
const getDevConfig = createTypedConfig<EnvConfig>();
const getProdConfig = createTypedConfig<EnvConfig>();

function loadConfig(): EnvConfig {
  const environment = process.env.NODE_ENV || 'development';
  const envFile = `.env.${environment}`;

  const { parsedEnv } = config<EnvConfig>({
    path: envFile,
    strict: true,
  });

  if (!validateEnv(parsedEnv, envSchema)) {
    throw new Error(`Invalid environment configuration in ${envFile}`);
  }

  return parsedEnv;
}

export const env = loadConfig();

// Usage with full type safety
console.log(`Database host: ${env.DATABASE_CONFIG.host}`); // TypeScript knows this is a string
console.log(`Connection pool max: ${env.DATABASE_CONFIG.pool.max}`); // TypeScript knows this is a number
env.API_ENDPOINTS.forEach((endpoint) => {
  // TypeScript provides full IntelliSense for the endpoint object
  console.log(`${endpoint.path}: ${endpoint.methods.join(', ')}`);
});

Type Safety Benefits

  • IntelliSense: Full autocomplete for object properties and array methods
  • Compile-time checking: Catch type errors before runtime
  • Refactoring safety: Rename properties with confidence across your codebase
  • Documentation: Types serve as living documentation for your environment structure
  • Runtime safety: Combined with validation, ensures type correctness at runtime

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request

License

MIT License - see LICENSE file for details.