envhero
v0.1.1
Published
A tiny but mighty Node.js package to make it easy to require and parse environment variables
Maintainers
Readme
A tiny but mighty Node.js package to make it easy to require and parse environment variables
envhero is intentionally simple and has zero runtime dependencies. Its job is to check your configuration as early as possible—ideally during your application's or Lambda's initialization phase—so missing or malformed environment variables fail fast, before any real work begins. 🦸
⚡ Install
npm install envheroThe package is available from the npm registry, so you can install it with pnpm, Yarn, Bun, or any other npm-compatible package manager:
pnpm add envhero
yarn add envhero
bun add envheroenvhero requires Node.js 24 or newer and is ESM-only.
🦸 Assemble your configuration
Read and validate environment variables once, near your application's entry point:
import { envBool, envInt, envStr, envStrList } from 'envhero'
export const config = {
databaseUrl: envStr('DATABASE_URL'),
logLevel: envStr('LOG_LEVEL', 'info'),
port: envInt('PORT', 3000),
debug: envBool('DEBUG', false),
allowedOrigins: envStrList('ALLOWED_ORIGINS', ['https://example.com']),
}If DATABASE_URL is missing or empty, module initialization throws immediately instead of letting a request discover the problem later.
import { envStr, MissingEnvError } from 'envhero'
try {
const secret = envStr('SUPER_SECRET')
} catch (error) {
if (error instanceof MissingEnvError) {
console.error(error.message)
}
throw error
}🛡️ API
envStr(name, defaultValue?)
Reads a string environment variable. An unset or empty ('') value returns defaultValue when provided; otherwise it throws MissingEnvError. Non-empty whitespace is preserved as a string value.
envStrList(name, defaultValue?)
Reads a comma-separated value as a string[], trimming each item and removing empty items. An unset or empty value uses the provided default or throws. A present value that contains no items, such as ',', returns [].
envInt(name, defaultValue?)
Reads an integer using JavaScript number conversion. Unset, empty, and whitespace-only values use the provided default or throw. A present value that is not an integer—such as '1.5' or 'abc'—always throws, even when a default exists.
envBool(name, defaultValue?)
Reads a boolean after trimming whitespace. The values '1', 'true', 'yes', 'enabled', and 'on' are true, case-insensitively; every other present value is false. Unset, empty, and whitespace-only values use the provided default or throw.
MissingEnvError
The error thrown when a required variable is missing or a required parse fails. Its message is missing required env var: NAME.
🎯 Philosophy
- Fail early. Validate configuration during initialization, not halfway through a request or job.
- Stay tiny. No schema language, decorators,
.envloader, or dependency tree. - Be predictable. A handful of typed helpers with explicit defaults and clear failure behavior.
- Work brilliantly in Lambdas. Put configuration at module scope so a cold start catches deployment mistakes immediately.
🙅 Not in the box (by design)
Because envhero aims for simplicity, a few things are deliberately out of scope. They are all easy to express with plain JavaScript, so the library stays tiny and predictable.
Optional variables
Every helper models a variable that is required or has a default. If a variable is genuinely optional, you don't need a library at all:
// `||` also coerces '' (an empty string) to undefined,
// consistent with how envhero treats empty values as unset
const region = process.env.AWS_REGION || undefinedMapping and additional validation
If you need to transform a value or validate it beyond presence and basic shape, compose an envhero helper with a few lines of plain code—for example, in an immediately invoked function:
import { envStr } from 'envhero'
const serviceUrl = (() => {
const raw = envStr('SERVICE_URL')
return new URL(raw) // still fails fast if the value is not a valid URL
})()Aren't closures and IIFEs (immediately invoked function expressions) very handy? Yes, they are indeed!
When your configuration calls for full schema validation, coercion, or cross-field rules, reach for a dedicated library such as zod see here: Validating environment variables with zod.
🛠️ Contributing
The development environment is reproducible with mise and uses pnpm:
mise install
mise run install
mise run checkmise run install also installs the Lefthook pre-commit quality gate. Tests use only Node.js built-in modules—there is no external test framework. See AGENTS.md for repository conventions and RELEASING.md for the release process.
📜 License
MIT © 2026 Luciano Mammino
