Type-safe environment variable and runtime config validation for TypeScript and JavaScript — zero dependencies, structured errors, and built-in validators for common process.env and app config use cases.
npm install valitype
import { validateValue, validators } from 'valitype'
const config = {
port: validateValue('PORT', process.env.PORT, { type: 'number', required: true }),
debug: validateValue('DEBUG', process.env.DEBUG, { type: 'boolean', default: false }),
apiUrl: validateValue('API_URL', process.env.API_URL, { type: 'url', required: true }),
env: validateValue('NODE_ENV', process.env.NODE_ENV, {
type: { enum: ['development', 'production', 'test'] },
default: 'development',
}),
apiKey: validateValue('API_KEY', process.env.API_KEY, {
type: 'custom',
validator: validators.regex(/^[a-z0-9]{32}$/),
required: true,
}),
}
If any value fails, a ValidationError is thrown with the field name, the received value, and a machine-readable code. Before your app ever starts.
validateValue returns the correct TypeScript type based on the ruleValidationError carries key, value, and code so you can handle failures programmaticallyhttp/https; date formats are actually enforcedZod, Joi, and Yup are great full schema validation libraries. Use them when you need complex object validation, nested schemas, arrays, forms, API payload validation, transformations, parsing pipelines, or advanced validation flows.
Use valitype when you need focused TypeScript and JavaScript validation for environment variables, process.env, package options, feature flags, and runtime config:
valitype is not a replacement for Zod, Joi, or Yup. It is a small alternative when a full schema validation framework would be more than you need.
valitype supports the following Node.js versions:
| Node.js | Status |
|---|---|
| 22 | Supported |
| 24 | Supported |
| 26 | Supported |
The test suite runs against all supported Node.js versions to ensure compatibility across the supported runtime matrix.
| Rule | Returns | Notes |
|---|---|---|
{ type: 'string' } |
string |
|
{ type: 'number' } |
number |
Decimal only — rejects hex, scientific notation |
{ type: 'boolean' } |
boolean |
Accepts 'true' or 'false' only |
{ type: 'url' } |
string |
Requires http or https scheme |
{ type: { enum: string[] } } |
string |
Must be one of the listed values |
{ type: 'custom', validator } |
string |
Bring your own logic |
All types accept required?: boolean and default?: T.
Use these with { type: 'custom', validator: ... }.
validators.regex(/^[A-Z]{3}$/, 'Must be 3 uppercase letters')
validators.range(1, 65535, 'Must be a valid port')
validators.oneOf(['us-east-1', 'eu-west-1'], 'Unsupported region')
validators.date('YYYY-MM-DD')
validators.json()
validators.awsArn('lambda')
validators.all(
validators.regex(/^[A-Z]/),
validators.oneOf(['Alpha', 'Beta', 'Gamma'])
)
validators.date('YYYY-MM-DD') enforces the format, not just parseability. validators.awsArn() supports all AWS partitions: aws, aws-cn, and aws-us-gov.
Every failure throws a ValidationError:
import { ValidationError } from 'valitype'
try {
validateValue('PORT', '0xff', { type: 'number', required: true })
} catch (err) {
if (err instanceof ValidationError) {
console.log(err.code) // 'INVALID_NUMBER'
console.log(err.key) // 'PORT'
console.log(err.value) // '0xff'
console.log(err.message) // 'PORT must be a valid number'
}
}
Available codes: REQUIRED · INVALID_NUMBER · INVALID_BOOLEAN · INVALID_URL · INVALID_ENUM · INVALID_CUSTOM · UNKNOWN_RULE
valitype is built with a minimal and transparent supply chain:
Contributions are welcome. See CONTRIBUTING.md.
This library is licensed under the MIT License. See the LICENSE file for details.