@steima/env-typecheck
v0.1.0
Published
Type-safe environment variable validation with Zod. Zero boilerplate, smart coercion, beautiful error messages.
Maintainers
Readme
env-typecheck
Type-safe environment variable validation with Zod.
Zero boilerplate. Smart coercion. Beautiful error messages.
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; // booleanOne 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 zodWhy 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, "" → undefinedNo 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.exampleOutput:
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, numberAPI 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.envonError— Error handling strategy:'throw'(default) — Throws an error with the formatted message'exit'— Prints the error and callsprocess.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
