@systemix/env

Typed environment variable loading and validation. Zero dependencies. Built-in .env file support.

Installation

pnpm add @systemix/env

Basic Usage

import { load } from '@systemix/env';

const env = load({
  NODE_ENV: { type: 'string', default: 'development' },
  PORT: { type: 'number', default: 3000 },
  DATABASE_URL: { type: 'string', required: true, secret: true },
  DEBUG: { type: 'boolean', default: false },
});

console.log(env.PORT); // number
console.log(env.toSafeLog()); // { DATABASE_URL: '***', ... }

Schema

PropertyTypeDescription
type'string' | 'number' | 'boolean'How to parse the value
requiredbooleanIf true, throws when missing
defaultstring | number | booleanUsed when var is missing or empty
minnumberMin value (number type)
maxnumberMax value (number type)
regexRegExpMust match (string type)
oneOfstring[]Allowed values (string type)
transform(raw) => valueCustom parser
secretbooleanMasked in toSafeLog()

Options

Pass options as second argument. For backward compat, a plain Record is treated as { source }:

load(schema, { PORT: '4000' }); // legacy: treated as source
load(schema, {
  source: { PORT: '4000' }, // Custom env source
  fromFile: '.env.local', // Load from .env file(s)
  fromFile: ['.env', '.env.local'], // Multiple files, later overrides
  strict: true, // Ignore vars not in schema
});

.env File Loading

Load from file. Cross-platform (Windows, macOS, Linux).

const env = load(schema, { fromFile: '.env.local' });

Or parse content yourself:

import { parseEnvFile } from '@systemix/env';

const vars = parseEnvFile(readFileSync('.env', 'utf-8'));

Secret Masking

Mark sensitive vars with secret: true. Use toSafeLog() for logging:

const env = load(
  {
    API_KEY: { type: 'string', secret: true },
    PORT: { type: 'number' },
  },
  { source: { API_KEY: 'sk-123', PORT: '3000' } },
);

console.log(env.toSafeLog());
// { API_KEY: '***', PORT: 3000 }

Batch Error Reporting

All validation errors are collected and thrown together:

Env validation failed:
  - Missing required env var: DATABASE_URL
  - PORT: must be >= 1

Config (OOP)

Class-based usage with get, getOrThrow, has:

import { Config } from '@systemix/env';

const config = Config.fromEnv({
  PORT: { type: 'number', default: 3000 },
  DATABASE_URL: { type: 'string', required: true },
});

config.get('PORT'); // number | undefined
config.get('PORT', 4000); // number (default when undefined)
config.getOrThrow('DATABASE_URL'); // throws if not set
config.has('PORT'); // boolean
config.toSafeLog(); // masked for logging
config.getRaw(); // raw env object

Create from existing env: Config.from(load(schema)).

Boolean Parsing

  • true: "true", "1", "yes"
  • false: "false", "0", "no", ""

Try it

Open the Env Loader demo to see live examples.