Converters

Turn a raw environment string into a typed value with the built-in converter tokens, the array builder, or your own function.

A converter turns the raw environment string into a typed value. Pass a built-in token to getUsing, a function to getWith, or either as the converter option on the @Envapt decorator. Without a converter, a value stays a string.

const timeout = .('TIMEOUT', ., '30s');
const timeout: number
const retries = .('RETRIES', () => ( ?? 0), 3);
const retries: number

Built-in tokens

Converters carries one token per built-in type, plus the array builder.

TokenReturnsParsed from
Converters.Stringstringthe raw value, unchanged
Converters.NumbernumberNumber(raw); NaN uses the fallback
Converters.IntegernumberparseInt(raw, 10)
Converters.FloatnumberparseFloat(raw)
Converters.Booleanboolean1/yes/true/on and 0/no/false/off
Converters.BigintbigintBigInt(raw)
Converters.SymbolsymbolSymbol.for(raw)
Converters.JsonJsonValueJSON.parse(raw)
Converters.UrlURLnew URL(raw)
Converters.RegexpRegExp/pattern/flags form, or the whole string as the pattern
Converters.DateDatea millisecond timestamp or a UTC ISO 8601 string
Converters.Timenumbera duration string like 30s, returned as milliseconds
const port = .('PORT', ., 3000);
const port: number
const apiUrl = .('API_URL', .);
const apiUrl: URL | undefined

A fallback removes undefined from the return type, the same way it does for the primitive readers. Without one, the return is T | undefined.

NOTE

A failed conversion never throws. Url, Json, Date, Regexp, and the number tokens swallow the parse error and return the fallback, or undefined when you gave none. Use the { required: true } form to throw on a malformed value instead.

Numbers: Number, Integer, Float

Number accepts anything JavaScript's Number() does, including floats, hex, and scientific notation. Integer stops at the first non-digit, so 42px reads as 42 and 3.9 reads as 3. Float parses a leading decimal and tolerates trailing text.

// COUNT=42px
const  = .('COUNT', .); // 42
const  = .('RATIO', ., 1.0);

JSON

Json runs JSON.parse. Invalid JSON returns the fallback. The return type is JsonValue, the recursive union of JSON-representable values, so narrow it before use.

// FEATURE_FLAGS={"beta":true}
const flags = .('FEATURE_FLAGS', ., {});
const flags: JsonValue

URL, RegExp, Date

Url builds a URL, so the value must be absolute; a relative path throws inside the constructor and returns the fallback.

Regexp reads a /pattern/flags literal (flags limited to g i m s u v y). A value without the surrounding slashes is treated as the whole pattern with no flags.

Date accepts exactly two forms:

// RELEASED_AT=2024-01-15T10:30:00Z
const released = .('RELEASED_AT', .);
const released: Date | undefined
WARNING

Date takes an all-digit millisecond timestamp, or a UTC ISO 8601 string ending in Z (2024-01-15T10:30:00Z, optionally with .mmm milliseconds). A date-only string, a local time, or an offset like +02:00 returns the fallback. Store dates in UTC.

Time and durations

Time reads a duration and returns it in milliseconds. The raw value takes a number with an optional unit; a bare number is milliseconds.

// CACHE_TTL=15m
const  = .('CACHE_TTL', .); // 900000
const grace = .('GRACE', ., '1.5h');
const grace: number

The units are ms, s, m, h, d, w. The fallback may be a number (already milliseconds) or a time-string.

WARNING

A raw env value is lenient: a unit is optional and decimals are allowed (1.5h). A string fallback is strict: it needs an integer and an explicit unit (90m, not 1.5h or 5400). A malformed string fallback throws EnvaptError with code MalformedTimeFallback.

Arrays

Converters.array splits the value on a delimiter and converts each element. The delimiter defaults to , and the element type defaults to string.

// CORS=https://a.com,https://b.com
const origins = .('CORS', .({ : . }));
const origins: URL[] | undefined
// PORTS=3000 3001 3002 const ports = .('PORTS', .({ : ., : ' ' }));
const ports: number[] | undefined

The element type can be any scalar token except Json and Regexp, or your own (raw: string) => T function that converts a single element. An array fallback must already be an array of the element type.

const  = (: string) => {
    const [, ] = .(':');
    return { : (), : () };
};

// COORDS=1:2,3:4
const points = .('COORDS', .({ :  }));
const points: {
    x: number;
    y: number;
}[] | undefined

Empty elements are dropped in normal mode. Under strict mode an empty element (a trailing comma, say) throws EnvaptError with code EmptyArrayElement instead of being filtered out.

DANGER

Under strict mode these throws come from env data, not your code. A trailing comma in a deployed .env throws EmptyArrayElement at read time, and an element your converter maps to undefined throws ArrayElementConversionFailed. A stray comma can stop startup.

Custom converters

When no built-in fits, pass a function to getWith. It receives the raw value (string, or undefined when the variable is unset) and the fallback, and returns the typed value. The function owns its own parsing and failure handling.

const  = (: string | undefined) => {
    const [, ] = ( ?? 'localhost:80').(':');
    return { , : () };
};

const pair = .('HOST_PORT', );
const pair: {
    host: string;
    port: number;
} | undefined

For a single array element you supply a (raw: string) => T function to array({ of }) instead. That element function receives only the trimmed, non-empty element string. Returning undefined from it throws EnvaptError with code ArrayElementConversionFailed.

Require a converted value

Both readers take an options form that throws on a missing value instead of returning a fallback.

const dbUrl = .('DATABASE_URL', { : ., : true });
const dbUrl: URL

See Fail-fast on missing values for require, and Standard Schema for validating a value through zod, valibot, or arktype.

On this page