Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

env-type-safe

CI

Type-safe environment variable loader with precise TypeScript typing, validation, and detailed multi-error reporting. Validates all variables upfront, coerces strings to proper types (number, boolean, URL, port), and returns an immutable configuration object.

Installation

npm install @ferrow/env-type-safe

Quick Start

import { loadEnv } from 'env-type-safe';

const config = loadEnv({
  PORT: { type: 'port', default: 3000 },
  DATABASE_URL: { type: 'url', required: true },
  DEBUG: { type: 'boolean', default: false },
  API_KEY: 'string',
});

console.log(config.PORT); // number, type-safe
console.log(config.DEBUG); // boolean

API

loadEnv<T>(schema: T): InferredConfig<T>

Loads and validates environment variables against a schema. Throws ValidationError if validation fails.

Schema field options:

  • type: 'string' | 'number' | 'boolean' | 'url' | 'port'
  • required: boolean (default: true)
  • default: value of the specified type

Type Coercion:

  • 'number': Parses string as decimal. NaN is an error.
  • 'boolean': Accepts 'true', 'false', '1', '0' (case-sensitive). Other values are errors.
  • 'url': Must be a valid URL per URL() constructor.
  • 'port': Must be an integer in range 1–65535.
  • 'string': Returned as-is.

Return type: Frozen (immutable) object with inferred field types.

Throws: ValidationError with array of issues listing all validation failures.

ValidationError

interface ValidationError extends Error {
  name: 'ValidationError';
  issues: { key: string; message: string }[];
}

Validation is all-or-nothing: if any field fails, all issues are collected and reported in one throw.

Examples

Valid configuration

process.env.PORT = '3000';
process.env.DATABASE_URL = 'postgresql://localhost/db';
process.env.DEBUG = 'true';

const config = loadEnv({
  PORT: { type: 'port', default: 5000 },
  DATABASE_URL: 'url',
  DEBUG: 'boolean',
});

config.PORT; // 3000 (number)
config.DATABASE_URL; // 'postgresql://localhost/db' (string)
config.DEBUG; // true (boolean)
Object.isFrozen(config); // true

Multiple validation errors

try {
  loadEnv({
    PORT: { type: 'port', required: true },
    API_KEY: 'string', // required by default
    DEBUG: { type: 'boolean', default: false },
  });
} catch (err) {
  if (err.name === 'ValidationError') {
    console.log(err.issues);
    // [
    //   { key: 'PORT', message: 'required but missing' },
    //   { key: 'API_KEY', message: 'required but missing' }
    // ]
  }
}

Type safety

TypeScript infers the shape of the returned config from the schema. Missing or incorrect environment variables are caught at validation time, not at access time.

const config = loadEnv({
  PORT: { type: 'port', default: 3000 },
  SECRET: 'string',
});

config.PORT; // ✓ number
config.SECRET; // ✓ string
config.MISSING; // ✗ TypeScript error (not in schema)

Limits

  • Environment variables are read once at loadEnv() call time. Changes to process.env afterwards are not reflected.
  • Returned config is frozen; mutations are prevented at runtime.
  • No support for structured/nested environment variables (JSON strings must be parsed manually).
  • Boolean coercion is strict: only 'true', 'false', '1', '0' are recognized.
  • URL and port validation follow Node.js standards (Node URL class and RFC 6335 port ranges).

License: MIT

Sponsored by Ferrow


Part of the ferrow-toolkit collection · Sponsored by Ferrow

About

Type-safe environment variable loader with schema validation, type coercion, and detailed error reporting

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages