envalid

Type-safe environment variable validation and cleanup for Node.js and Bun with zero runtime dependencies.

Library
npm
v8.2.0
1,591stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
65/100Good
Development Activity68
Maintenance52
Community52
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture88
Code Quality92
Innovation85
Learning Curve55

Envalid validates and sanitizes environment variables for Node.js, Bun, and other JS runtimes, ensuring a program only starts when all of its required environment dependencies are present and well-formed. Built entirely in TypeScript with strong type inference and zero runtime dependencies, it wraps process.env in a frozen, strictly-typed object so validated env vars can’t drift or be mutated once the app is running.

Beyond basic presence checks, envalid ships built-in validators for strings, booleans, numbers, emails, hosts, ports, URLs, and JSON, plus devDefault/testDefault fallbacks that adapt required vars per NODE_ENV, custom validators via makeValidator, and a pluggable reporter/middleware system for teams who want to customize error handling or extend the cleaned env object.

What You Get

  • Built-in validators for str, bool, num, email, host, port, url, and json env var types
  • An immutable, proxy-wrapped env object that throws on unvalidated property access or mutation attempts
  • Environment-aware defaults via default, devDefault, and testDefault, so required vars can differ by NODE_ENV
  • isDev/isProd/isTest convenience accessors computed automatically from NODE_ENV
  • Custom validator and reporter APIs (makeValidator, customCleanEnv) for extending validation and error handling

Common Use Cases

  • Validating required API keys and secrets before a Node.js server boots, failing fast with a readable error list
  • Enforcing different required env vars for production vs. local development using devDefault
  • Type-safe access to environment configuration in TypeScript projects, with types inferred directly from validator specs
  • Providing executable documentation of an app’s environment requirements for new contributors

Under The Hood

Architecture Envalid is a small functional pipeline rather than a class hierarchy: core.ts’s getSanitizedEnv() iterates each validator spec, reads the raw value via readRawEnvValue(), applies default/devDefault/testDefault fallback logic keyed off NODE_ENV, and delegates actual parsing to each spec’s _parse function (defined in validators.ts and created by the factories in makers.ts); envalid.ts’s cleanEnv() then hands the sanitized object to middleware.ts, which layers on accessorMiddleware (computes isDev/isProd/isTest) and strictProxyMiddleware (a Proxy that throws ReferenceError on unvalidated reads or any write) before Object.freeze() locks it down; customCleanEnv() exposes the same pipeline with a swappable middleware step for advanced use. The separation between spec validation (core), validator definitions (validators/makers), and post-processing (middleware) keeps each layer independently testable, and swapping the core validation algorithm would only require changes to core.ts without touching the public cleanEnv surface.

Tech Stack The library is pure TypeScript compiled with tsc (no bundler), has zero runtime dependencies, and is tested with Vitest (including a coverage command) across a Node.js 20/22/24 CI matrix using Bun for dependency installation. Biome handles both linting and formatting, @arethetypeswrong/cli checks that the published package’s type exports are correct, and Husky enforces lint+tsc on pre-commit and the full test suite on pre-push.

Code Quality The project has an extensive Vitest test suite spanning basics, validators, middleware, error subclassing, requiredWhen conditional logic, and dedicated type-level tests (using expect-type) that assert the inferred TypeScript types are correct, not just the runtime behavior. Errors are explicit and typed via custom EnvError/EnvMissingError subclasses rather than swallowed, naming conventions are consistent and minimal, and CI enforces type-checking, linting, and the test suite on every push across multiple Node versions, with a separate CodeQL workflow for security scanning.

What Makes It Unique Rather than reusing a general-purpose schema validator, envalid’s API is purpose-built around the specific shape of environment-variable configuration: devDefault/testDefault let a var be strictly required in production while auto-filling sensible values in development and test based on NODE_ENV, and requiredWhen allows one var to become conditionally required based on the rest of the already-cleaned environment. The strict proxy wrapper is a distinctive enforcement mechanism, turning a typo’d or unvalidated env var access into an immediate, descriptive runtime error instead of a silent undefined.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search