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

@dharaneesh/env-schema-validator

v1.0.1

Published

Zero-dependency TypeScript-first .env validator. Fails fast with clear, human-readable errors.

Readme

@dharaneesh/env-schema-validator

npm version license zero dependencies types

Zero-dependency, TypeScript-first .env validator. Validates all environment variables at startup, returns a fully typed object, and tells you everything that's wrong — all at once.


The Problem

// ❌ Without this package — crashes at runtime, no types, no helpful errors
const port = Number(process.env.PORT);        // NaN if PORT is missing
const db   = process.env.DATABASE_URL;        // string | undefined, no safety
const flag = process.env.DEBUG === "true";    // works, but fragile

You only discover missing or malformed env vars when your app crashes in production — not at startup.


The Solution

import { validateEnv } from "@dharaneesh/env-schema-validator";

const env = validateEnv({
  PORT:         { type: "number",  default: "3000" },
  DATABASE_URL: { type: "url",     description: "PostgreSQL connection string" },
  NODE_ENV:     { type: "string",  enum: ["development", "production", "test"] },
  DEBUG:        { type: "boolean", required: false, default: "false" },
  ADMIN_EMAIL:  { type: "email",   required: false },
});

// ✅ Fully typed — no casting needed
env.PORT         // number
env.DATABASE_URL // string (guaranteed valid URL)
env.DEBUG        // boolean

If anything is wrong, you get one clear error at startup — before your server even starts:

EnvValidationError: Environment validation failed:

  ✗ DATABASE_URL: is required but not set (PostgreSQL connection string)
  ✗ PORT: must be a number, got "abc"
  ✗ NODE_ENV: must be one of [development, production, test], got "prod"

Installation

npm install @dharaneesh/env-schema-validator

No other dependencies needed. Works with Node.js 18+, ESM and CJS projects.


Usage

Basic

import { validateEnv } from "@dharaneesh/env-schema-validator";

const env = validateEnv({
  APP_NAME: { type: "string" },
  PORT:     { type: "number", default: "3000" },
  DEBUG:    { type: "boolean", required: false, default: "false" },
});

console.log(env.PORT);  // 3000 (number, not string)
console.log(env.DEBUG); // false (boolean, not string)

With dotenv

import "dotenv/config"; // loads .env into process.env first
import { validateEnv } from "@dharaneesh/env-schema-validator";

const env = validateEnv({
  DATABASE_URL: { type: "url" },
  JWT_SECRET:   { type: "string" },
});

Recommended — shared config module

Create one file that validates everything at startup. Import it everywhere.

// src/config.ts
import { validateEnv } from "@dharaneesh/env-schema-validator";

export const config = validateEnv({
  NODE_ENV:     { type: "string",  enum: ["development", "production", "test"] },
  PORT:         { type: "number",  default: "3000" },
  DATABASE_URL: { type: "url",     description: "PostgreSQL connection string" },
  REDIS_URL:    { type: "url",     required: false },
  JWT_SECRET:   { type: "string",  description: "At least 32 characters" },
  JWT_EXPIRES:  { type: "string",  default: "7d" },
  DEBUG:        { type: "boolean", required: false, default: "false" },
  ADMIN_EMAIL:  { type: "email",   required: false },
  SMTP_HOST:    { type: "string",  required: false },
  SMTP_PORT:    { type: "number",  required: false, default: "587" },
});

// Now import config anywhere:
// import { config } from "./config";
// config.PORT        → number
// config.DATABASE_URL → string
// config.DEBUG       → boolean

Validate a custom object (not process.env)

const env = validateEnv(
  { PORT: { type: "number" } },
  { PORT: "8080" }  // pass any Record<string, string | undefined>
);

Schema Reference

Every key in your schema maps to a FieldSchema object:

| Field | Type | Default | Description | |---------------|---------------------------------------------------|----------|----------------------------------------------| | type | "string" \| "number" \| "boolean" \| "url" \| "email" | — | How to validate and coerce the raw value | | required | boolean | true | If false, missing field is skipped | | default | string | — | Raw string used when field is absent | | enum | string[] | — | Restricts to a list of allowed values | | description | string | — | Shown in the error message when field fails |


Types Explained

| Type | What it accepts | JS output | |-----------|---------------------------------------------------------|-------------| | string | Any non-empty string | string | | number | Any numeric string ("3000", "3.14", "-1") | number | | boolean | true, false, 1, 0, yes, no, on, off | boolean | | url | Any string parseable by new URL() (must include protocol) | string | | email | Basic [email protected] format | string |

Boolean coercion is case-insensitiveTRUE, True, YES all work.


API

validateEnv(schema, source?)

function validateEnv<S extends EnvSchema>(
  schema: S,
  source?: Record<string, string | undefined>  // defaults to process.env
): ValidatedEnv<S>
  • On success — returns a typed ValidatedEnv<S> object with all values coerced to their proper JS types.
  • On failure — throws EnvValidationError with all problems listed, not just the first one.

EnvValidationError

import { validateEnv, EnvValidationError } from "@dharaneesh/env-schema-validator";

try {
  const env = validateEnv(schema);
} catch (err) {
  if (err instanceof EnvValidationError) {
    // Human-readable multi-line string — log this
    console.error(err.message);

    // Machine-readable array — use this programmatically
    err.errors.forEach(({ key, message }) => {
      console.error(`${key}: ${message}`);
    });

    process.exit(1);
  }
}

err.errors is an array of { key: string; message: string } objects, one per failed field.


Why Not Just Use envalid or zod?

| Feature | dotenv | envalid | zod | @dharaneesh/env-schema-validator | |----------------------------------|:--------:|:---------:|:-----:|:------------------------:| | Zero runtime dependencies | ✅ | ❌ | ❌ | ✅ | | TypeScript types from schema | ❌ | ✅ | ✅ | ✅ | | URL + email types built-in | ❌ | ✅ | ❌ | ✅ | | Reports ALL errors at once | ❌ | ✅ | ✅ | ✅ | | ESM + CJS dual output | ❌ | ❌ | ✅ | ✅ | | Single file, no config needed | ❌ | ❌ | ❌ | ✅ |


TypeScript Support

Full types come included — no @types/ package needed.

import { validateEnv, EnvSchema, ValidatedEnv, EnvValidationError } from "@dharaneesh/env-schema-validator";

const schema = {
  PORT: { type: "number" as const },
  NAME: { type: "string" as const },
} satisfies EnvSchema;

type AppEnv = ValidatedEnv<typeof schema>;
// { PORT: number; NAME: string }

Example .env File

NODE_ENV=production
PORT=3000
DATABASE_URL=postgres://user:pass@localhost:5432/mydb
JWT_SECRET=my-very-long-secret-key-here
DEBUG=false
[email protected]

Contributing

git clone https://github.com/dharaneesh-r/@dharaneesh/env-schema-validator
cd @dharaneesh/env-schema-validator
npm install
npm test          # run tests
npm run test:watch  # watch mode
npm run build     # build dist/

License

MIT © Dharaneesh R