Skip to content

ultrox/env

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@ma.vu/env

Zero-dependency env validation with a builder API. Type-safe, no schema library needed.

npm codecov

Why

Most apps validate env vars at runtime — the app boots, reads process.env, and crashes if something's missing. By then it's too late: you've deployed, the container is up, and you're staring at logs wondering why nothing works.

The schema should live in its own file so it can be imported by both your app and your CI pipeline. Validate before deploy, not after. If a required var is missing, the build fails — not the production server.

Env vars are strings. You need to know: is it present? What type? Any length constraints? That's it. No reason to pull in a schema library for that.

  • Zero runtime dependencies
  • Full TypeScript inference — parse() returns typed data matching your schema
  • Immutable builder API — .min(), .max() return new descriptors
  • parse() throws on missing required vars, warns on missing optional vars

Install

npm install @ma.vu/env

Usage

Define a schema

// config/env.config.ts
import { createEnv, required, optional, number, boolean } from '@ma.vu/env';

export const env = createEnv({
  CLERK_SECRET_KEY: required,
  API_KEY: required.min(5).max(100),
  DATABASE_URL: optional,
  PORT: number,
  DEBUG: boolean,
});

Use in your app

// config/app.config.ts
import { env } from './env.config';

const { data, warnings } = env.parse(process.env);
// Throws if required vars are missing
// Warns about missing optional vars

export const config = data;
// config.CLERK_SECRET_KEY → string
// config.PORT             → number
// config.DEBUG            → boolean

Generate .env in CI

// bin/validate-env.ts
import { env } from '../src/server/config/env.config.js';

const source = process.argv[2];
const output = process.argv[3];

if (!(source && output)) {
  throw new Error('Usage: validate-env <json> <output-path>');
}

env.writeEnvFile({ source, output });
- name: Generate and validate .env
  run: npx tsx bin/validate-env.ts '${{ toJSON(secrets) }}' .env.deploy

secrets is a GitHub Actions context object containing all repo secrets. toJSON() serializes it into a single JSON string so you don't have to list each secret individually. writeEnvFile accepts it directly (string or object), validates against the schema (throws on errors), and writes a .env file. Empty optional values are skipped.

API

Primitives

Export Type Behavior
required string Trimmed, must be non-empty (min length 1)
optional string Trimmed, defaults to "", appears in warnings if missing
number number Coerced via Number(), error if NaN
boolean boolean "true"/"1" → true, "false"/"0"/"" → false

Modifiers

.min(n) and .max(n) return new descriptors (immutable):

required            // trimmed, min 1
required.min(5)     // trimmed, min 5
required.max(100)   // trimmed, max 100
optional.max(255)   // trimmed, defaults "", max 255 if provided
number.min(1).max(65535) // numeric range

createEnv(schema)

Returns an object with:

  • parse(source) — validates source against the schema. Throws on errors, warns on missing optional. Returns { data, warnings }
  • writeEnvFile({ source, output }) — validates and writes a .env file. Throws on errors
  • keys — array of all keys from the schema

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors