envase
v1.0.2
Published
Type-safe environment variable validation with Standard Schema compliance
Maintainers
Readme
Envase
Type-safe environment variable validation with Standard Schema compliance. Works with Zod, Valibot, ArkType, and other Standard Schema-compatible validation libraries.
"Envase" is Spanish for "container" - reflecting how this library encapsulates environment variables in a safe, structured, and validated way.
Highlights
- 🔒 Type-safe validation - Full TypeScript type inference
- 🔌 Standard Schema compliant - Works with any compatible validation library
- 🌐 Runtime agnostic - Runs anywhere (Node, Bun, Deno, browsers)
- 🏗️ Structured configuration - Supports nested config objects
- 🚦 Environment detection -
isProduction,isTest,isDevelopmentflags - 📜 Detailed error reporting - See all validation failures at once
- 🚀 Lightweight - Single dependency (type-fest), zero runtime overhead
Installation
npm install envaseNote: This package is ESM-only. It does not support CommonJS require(...).
Validation Library Support
Built on the Standard Schema specification, Envase works seamlessly with any schema library that implements the spec. See the full list of compatible libraries.
Popular options include:
Key features
Type-Safe Validation of Nested Schema
import { parseEnv, envvar } from 'envase';
import { z } from 'zod';
const config = parseEnv(process.env, {
app: {
listen: {
port: envvar('PORT', z.coerce.number().int().min(0).max(65535)),
},
},
db: {
host: envvar('DB_HOST', z.string().min(1).default('localhost')),
},
apiKey: envvar('API_KEY', z.string().min(32).optional()),
});
// config.app.listen.port -> number
// config.db.host -> string
// config.apiKey -> string | undefinedEnvironment Detection
import { detectNodeEnv } from 'envase';
const nodeEnv = detectNodeEnv(process.env);
// nodeEnv.isProduction -> boolean
// nodeEnv.isTest -> boolean
// nodeEnv.isDevelopment -> booleanThese flags are inferred from the NODE_ENV value (i.e. 'production', 'test', or 'development').
Detailed error reporting
import { parseEnv, envvar, EnvaseError } from 'envase';
import { z } from 'zod';
try {
parseEnv(process.env, {
apiKey: envvar('API_KEY', z.string().min(32)),
db: {
host: envvar('DB_HOST', z.string().min(1)),
},
});
} catch (error: unknown) {
if (EnvaseError.isInstance(error)) {
error.message
// Environment variables validation has failed:
// [API_KEY]:
// String must contain at least 32 character(s)
// (received: "short")
//
// [DB_HOST]:
// Required
// (received: "undefined")
error.issues
// [
// {
// "name": "API_KEY",
// "value": "short",
// "messages": ["String must contain at least 32 character(s)"]
// },
// {
// "name": "DB_HOST",
// "value": undefined,
// "messages": ["Required"]
// }
// ]
}
}Type Inference
import { envvar, type InferEnv } from 'envase';
import { z } from 'zod';
const envSchema = {
apiKey: envvar('API_KEY', z.string().min(32)),
db: {
host: envvar('DB_HOST', z.string().min(1)),
},
};
type Config = InferEnv<typeof envSchema>;
// { apiKey: string; db: { host: string } }API Reference
envvar
envvar(name: string, schema: StandardSchemaV1<T>)
Wraps a variable name and its schema for validation. This helps pair the raw env name with the shape you expect it to conform to.
parseEnv
parseEnv(env: Record<string, string | undefined>, envSchema: T)
Validates envvars against the schema and returns a typed configuration object.
detectNodeEnv
detectNodeEnv(env: Record<string, string | undefined>)
Standalone utility that reads NODE_ENV and returns an object with the following boolean flags:
- isProduction: true if NODE_ENV === 'production'
- isTest: true if NODE_ENV === 'test'
- isDevelopment: true if NODE_ENV === 'development'
EnvaseError
Thrown when validation fails.
Contains:
message: Human-readable error summaryissues: Array of validation issues with:name: Environment variable namevalue: Invalid value receivedmessages: Validation error messages
Why Envase?
- ✅ Works with any schema lib that follows the Standard Schema spec
- 🔄 Supports deeply nested configs
- 🔍 Offers rich error reporting with detailed issue breakdowns
Contributing
Contributions are welcome! If you’d like to improve this package, feel free to open an issue or submit a pull request. 🚀
