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

@steima/env-typecheck

v0.1.0

Published

Type-safe environment variable validation with Zod. Zero boilerplate, smart coercion, beautiful error messages.

Readme

env-typecheck

Type-safe environment variable validation with Zod.

Zero boilerplate. Smart coercion. Beautiful error messages.

npm version license


The Problem

// Every Node.js app ever:
const port = parseInt(process.env.PORT!); // NaN at runtime?
const debug = process.env.DEBUG; // "false" is truthy!
const dbUrl = process.env.DATABASE_URL; // undefined in production?

process.env is Record<string, string | undefined>. No types, no validation, no coercion. Your app crashes at runtime instead of at startup.

The Solution

import { defineEnv } from 'env-typecheck';
import { z } from 'zod';

export const env = defineEnv({
  DATABASE_URL: z.string().url(),
  PORT: z.number().default(3000),
  DEBUG: z.boolean().default(false),   // "false" → false (not true!)
  NODE_ENV: z.enum(['development', 'staging', 'production']),
  API_KEY: z.string().min(1),
  RETRY_DELAY: z.number().optional(),
});

env.PORT;         // number (fully typed)
env.DATABASE_URL; // string
env.DEBUG;        // boolean

One function. One import. Full type safety.

Error Messages

When validation fails, you get this:

╔══════════════════════════════════════════════════╗
║  ❌ Environment validation failed (3 errors)     ║
╠══════════════════════════════════════════════════╣
║                                                  ║
║  API_KEY        ✗ Required                       ║
║                   Variable is not set            ║
║                                                  ║
║  DATABASE_URL   ✗ Invalid url                    ║
║                   Received: "not-a-url"          ║
║                                                  ║
║  PORT           ✓ 3000 (default)                 ║
║  DEBUG          ✓ false (default)                ║
║  NODE_ENV       ✓ "production"                   ║
║  RETRY_DELAY    ✓ (not set, optional)            ║
║                                                  ║
║  💡 Missing variables for .env:                  ║
║  API_KEY=                                        ║
║  DATABASE_URL=                                   ║
╚══════════════════════════════════════════════════╝

Every variable. At a glance. Copy-paste ready.

Installation

npm install env-typecheck zod

Why not X?

| Feature | env-typecheck | t3-env | envalid | dotenv | |---|---|---|---|---| | Zod schemas | ✓ | ✓ | ✗ | ✗ | | Smart "false"false | ✓ | ✗ | ✗ | ✗ | | Zero boilerplate | ✓ | ✗ (runtimeEnv) | ✓ | ✓ | | Framework agnostic | ✓ | ✗ (Next.js) | ✓ | ✓ | | Beautiful errors | ✓ | ✗ | ✗ | ✗ | | Type inference | ✓ | ✓ | partial | ✗ | | .env.example CLI | ✓ | ✗ | ✗ | ✗ | | Validation | ✓ | ✓ | ✓ | ✗ |

Features

Smart String Coercion

Environment variables are always strings. env-typecheck automatically coerces them based on your Zod schema:

// Boolean — the pain point everyone has
"true"  → true       "false" → false
"1"     → true       "0"     → false
"TRUE"  → true       "FALSE" → false
""      → undefined  (so defaults kick in)

// Number
"3000"  → 3000       "3.14"  → 3.14
""      → undefined  "abc"   → Zod error

// String
unchanged, "" → undefined

No more z.coerce.boolean() turning "false" into true.

Type Inference

Full TypeScript inference out of the box:

const env = defineEnv({
  PORT: z.number().default(3000),
  API_KEY: z.string(),
  DEBUG: z.boolean().optional(),
});

// typeof env = {
//   readonly PORT: number;
//   readonly API_KEY: string;
//   readonly DEBUG: boolean | undefined;
// }

CLI: .env.example Generator

Generate a .env.example file from your schema:

npx env-typecheck generate --input ./src/env.ts --output .env.example

Output:

DATABASE_URL=        # Required, url
PORT=3000            # Optional, number (default: 3000)
DEBUG=false          # Optional, boolean (default: false)
NODE_ENV=            # Required, enum: development | staging | production
API_KEY=             # Required, string, min: 1
RETRY_DELAY=         # Optional, number

API Reference

defineEnv(schema, options?)

Parameters

  • schema — An object where keys are environment variable names and values are Zod schemas.
  • options (optional):
    • source — The environment object to read from. Default: process.env
    • onError — Error handling strategy:
      • 'throw' (default) — Throws an error with the formatted message
      • 'exit' — Prints the error and calls process.exit(1)
      • (errors) => void — Custom error handler

Returns

A frozen, fully-typed object with validated environment values.

export const env = defineEnv({
  DATABASE_URL: z.string().url(),
  PORT: z.number().default(3000),
}, {
  source: process.env,
  onError: 'throw',
});

CLI Reference

env-typecheck generate

env-typecheck generate --input <file> [--output <file>]

| Option | Description | Default | |---|---|---| | --input, -i | Path to your env schema file | (required) | | --output, -o | Output file path | .env.example |

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

MIT — Matthias Steinbauer