@spectroniqltd/strictenv
v0.1.0
Published
Zero-dependency TS micro-library that turns process.env into a typed, validated, auto-coercing boot-time check.
Maintainers
Readme
strictenv
Zero-dependency TypeScript micro-library that turns process.env into a typed, validated, auto-coercing boot-time check.
Published by Spectroniq Limited.
process.env is untyped (string | undefined). A missing required var crashes deep inside your app at some unpredictable moment instead of failing fast at boot; numbers and booleans need manual coercion every time. strictenv defines your expected env vars once, coerces and validates them at startup, and halts immediately with a readable report if anything's wrong.
Install
npm install @spectroniqltd/strictenvUsage
import { defineEnv } from "@spectroniqltd/strictenv";
const env = defineEnv({
PORT: { type: "number", default: 3000 },
DATABASE_URL: { type: "string", required: true },
DEBUG: { type: "boolean", default: false },
});
env.PORT; // number
env.DATABASE_URL; // string
env.DEBUG; // booleanIf DATABASE_URL is missing, the process halts immediately with a color-coded table naming every missing/invalid variable, then process.exit(1) — before the rest of your app ever boots.
Loading .env files
const env = defineEnv(
{
PORT: { type: "number", default: 3000 },
DATABASE_URL: { type: "string", required: true },
},
{
path: [".env", ".env.local"], // loaded in order, later files win
override: false, // real process.env wins over file values (default)
},
);.env files are parsed in-house (no dotenv dependency): comments (#), blank lines, single-quoted (literal) and double-quoted (with \n/\"/\\ escapes) values, and unquoted values are all supported. A missing file in path is silently skipped.
Custom failure handling
const env = defineEnv(
{ DATABASE_URL: { type: "string", required: true } },
{
onError: (errors) => {
// errors: { key, reason: "missing" | "invalid", raw, expectedType }[]
throw new Error(`Bad config: ${errors.map((e) => e.key).join(", ")}`);
},
},
);API
function defineEnv<S extends EnvSchema>(schema: S, options?: DefineEnvOptions): InferEnv<S>;
type EnvFieldConfig =
| { type: "string"; required?: boolean; default?: string }
| { type: "number"; required?: boolean; default?: number }
| { type: "boolean"; required?: boolean; default?: boolean };
type DefineEnvOptions = {
path?: string | string[]; // default: [".env"]
override?: boolean; // default: false (real process.env wins)
onError?: (errors: EnvError[]) => void; // default: print table + process.exit(1)
};A field is non-optional in the returned type when it's required: true or has a default — otherwise it's T | undefined.
Constraints
- Zero runtime dependencies
- <2KB gzipped
- Full TypeScript inference from the config object — no manual type annotations needed
- Node-only (
process.env,process.exit, file reads) - CJS + ESM builds
License
MIT
