Read a service’s settings once, at startup, and fail fast when one is missing or malformed:
ts
import { createEnvironmentReader } from 'jg-env';const { readBoolean, readEnum, readInteger, readString } = createEnvironmentReader(process.env);export const NODE_ENV = readEnum('NODE_ENV', ['development', 'production', 'test']);export const PORT = readInteger('PORT'); // only plain decimal digits, so 1e3 and 0x10 failexport const DATABASE_HOST = readString('DATABASE_HOST');export const MAINTENANCE_MODE = readBoolean('MAINTENANCE_MODE'); // exactly true or false
The same readers take any record of variables, such as Vite’s import.meta.env, whose built-in fields are booleans: only string values count, and anything else is invalid. A variable that’s absent, empty, or blank is unset. readOptionalString, readOptionalBoolean, readOptionalInteger, and readOptionalJson return undefined for an unset variable instead of throwing.
Read JSON settings through a schema, such as a Zod schema:
ts
import { createEnvironmentReader } from 'jg-env';import { z } from 'zod';const { readJson } = createEnvironmentReader(process.env);export const ALLOWED_ORIGINS = readJson('ALLOWED_ORIGINS', z.array(z.url()));
Secret files
jg-env/node reads secrets kept in files, such as Docker secrets. Inside a container, the secret’s variable holds the path to its file; elsewhere, the file is <KEY>.txt in a secrets directory:
ts
import { fileURLToPath } from 'node:url';import { createSecretReader } from 'jg-env/node';import { z } from 'zod';const { readSecret, readSecretJson } = createSecretReader({ isRunningInContainer: process.env['IS_RUNNING_IN_CONTAINER'] === 'true', secretsDirectoryPath: fileURLToPath(new URL('../secrets/', import.meta.url)),});export const DATABASE_PASSWORD = readSecret('DATABASE_PASSWORD'); // as it is, without trimmingexport const ROOT_ACCOUNT = readSecretJson('ROOT_ACCOUNT', z.object({ email: z.email() }));
Errors
Code
When
ENV_VARIABLE_MISSING
A required variable is unset
ENV_VARIABLE_INVALID
A value isn’t a string, an allowed value, true or false, a plain integer, JSON, or its schema’s
ENV_SECRET_FILE_UNREADABLE
A secret’s file is missing, unreadable, or empty
An error’s message and data name the variable, never its value. ENV_VARIABLE_INVALID has no cause, because a JSON parser’s or a schema’s error can quote the value. Inside a container, ENV_SECRET_FILE_UNREADABLE leaves out the path and the file system’s error too, since a variable set to the secret itself by mistake would otherwise print it.
Generated from TSDoc
API reference
Every export of [email protected], 8 in all, with its signature, its errors, and an example.
Creates the readers for a source of environment variables. Each read looks the variable up again, so it sees the source's current value. A variable is unset when the source doesn't hold it, or holds an empty or blank string; any other value that isn't a string is invalid. Errors name the variable and never its value.
reads a source's variables, each time from its current values. A required read of an unset variable throws ENV_VARIABLE_MISSING, and a value that can't be used throws ENV_VARIABLE_INVALID, without a cause, so neither ever holds the value
where the variables come from, such as process.env or Vite's import.meta.env. Only string values count as set, so a source may hold other values, such as import.meta.env's booleans
Declaration
type IEnvironmentSource = Readonly<Record<string, unknown>>;
Creates the readers for secrets kept in files, such as Docker secrets. Inside a container, each secret's variable holds the path to its file; elsewhere, the file is <KEY>.txt in the secrets directory. A file is read as it is, without trimming. Errors name the secret and never its value, and inside a container they leave out the path and the file system's error, which repeat whatever the variable holds.
reads secrets from files, at startup. A missing, unreadable, or empty file throws ENV_SECRET_FILE_UNREADABLE, and inside a container that error never names the path, since the path comes from a variable that might hold the secret itself by mistake