Validators & Format Presets
Custom Validators
Supply a validate function for domain-specific checks like port ranges, URL formats, or email patterns:
ts
const env = createEnv({
PORT: {
type: "number",
required: true,
validate: (v) => v >= 1 && v <= 65535,
},
API_URL: {
type: "string",
required: true,
validate: (v) => v.startsWith("https://"),
},
});If validation fails:
❌ 'PORT': Custom validation failed for value '99999'.validatereceives the parsed value (not the raw string).- It runs after type parsing and coercion.
- Returning
falsetriggers a validation error; returningtruepasses. - Skipped for missing optional variables (no value to validate).
- Runs on default values too — a bad default is caught at startup.
Conditional required
Instead of a static boolean, required can be a function that receives the full process.env and returns a boolean. This lets you make a variable required only when another variable has a specific value:
ts
const env = createEnv({
SMTP_HOST: { type: "string", required: true },
SMTP_USER: {
type: "string",
required: (env) => env.SMTP_HOST !== undefined,
},
SMTP_PASS: {
type: "string",
required: (env) => env.SMTP_HOST !== undefined,
},
});The function is evaluated at startup (and on every refresh() call in watch mode), giving you dynamic conditional required logic without any extra wiring.
String Format Presets
Use format for built-in validation of common string formats:
ts
const env = createEnv({
API_URL: { type: "string", format: "url", required: true },
CONTACT: { type: "string", format: "email", required: true },
SERVER_IP: { type: "string", format: "ip", required: true },
APP_PORT: { type: "string", format: "port", required: true },
REQUEST_ID: { type: "string", format: "uuid", required: true },
});| Format | Validates |
|---|---|
url | Parseable URL (new URL()) |
email | Basic user@host.tld pattern |
ip | IPv4 or IPv6 address |
port | Integer between 1 and 65 535 |
uuid | RFC 4122 hex-and-dash format |
If the value doesn't match:
❌ 'API_URL': Value 'not-a-url' does not match format 'url'.TIP
format is only available for type: "string" variables. For number or boolean validation, use validate or choices.