β valienv
A simple environment variables validator for Node.js and web browsers.
Installation
$ npm i valienv --save
# --- or ---
$ yarn add valienv
π
Basic usage
This library exports a main function: validateEnv
.
Using validators
, you can parse, validate and type required environment variables (other variables will be excluded).
import { bool, nbr, str, validateEnv } from "valienv";
// with process.env = {
// ACCENT_COLOR: "#0099e5",
// TIMEOUT_MS: "5000",
// ENABLE_ANALYTICS: "true",
// }
export const env = validateEnv({
env: process.env,
validators: {
// we validate env using bundled validators
ACCENT_COLOR: str,
TIMEOUT_MS: nbr,
ENABLE_ANALYTICS: bool,
},
});
// -> typeof env = Readonly<{
// ACCENT_COLOR: string;
// TIMEOUT_MS: number;
// ENABLE_ANALYTICS: boolean;
// }>
EnvValidationError
exposing invalidVariables
and missingVariables
names (not their values) to prevent your application from starting.
π
Advanced usage
The validateEnv
function accepts prefix
and overrides
options.
prefix
Some bundlers only expose prefixed environment variables to your application (ex: Create React App, Vite).
The prefix
option is very useful to remove them.
import { str, validateEnv } from "valienv";
// with process.env = {
// REACT_APP_CONTACT_EMAIL: "[email protected]",
// }
export const env = validateEnv({
env: process.env,
prefix: "REACT_APP_",
validators: {
CONTACT_EMAIL: str,
},
});
// -> typeof env = Readonly<{ CONTACT_EMAIL: string }>
overrides
The overrides
option is useful to override some variables in some contexts.
import { str, validateEnv } from "valienv";
// with process.env = {
// CONTACT_EMAIL: "[email protected]",
// }
export const env = validateEnv({
env: process.env,
validators: {
CONTACT_EMAIL: str,
},
overrides: {
...(process.env.NODE_ENV === "test" && {
CONTACT_EMAIL: "no-mail",
}),
},
});
// -> typeof env = Readonly<{ CONTACT_EMAIL: string }>
π§
Custom validators
By default, valienv
only exports 3 validators: str
(for string
), nbr
(for number
) and bool
(for boolean
).
But it's very easy to write your own:
import { validateEnv, Validator } from "valienv";
// A validator take raw input, try to parse it and
// returns the result in case of valid value:
const port: Validator<number> = (value /*: string*/) => {
const parsed = parseInt(value);
if (parsed > 0 && parsed < 65536) {
return parsed;
}
};
// with process.env = {
// PORT: "3000",
// }
export const env = validateEnv({
env: process.env,
validators: {
PORT: port,
},
});
// -> typeof env = Readonly<{ PORT: number }>
You can even go wild by using stricter types, complex parsing, your favorite validation library, etc!
import validator from "validator";
import { validateEnv } from "valienv";
// with process.env = {
// ETHEREUM_ADDRESS: "0xb794f5ea0ba39494ce839613fffba74279579268",
// NODE_ENV: "development",
// OPENED_COUNTRIES: "FR,BE,DE",
// }
export const env = validateEnv({
env: process.env,
validators: {
// inlined validators return types are correctly infered
ETHEREUM_ADDRESS: (value) => {
if (validator.isEthereumAddress(value)) {
return value;
}
},
NODE_ENV: (value) => {
if (
value === "development" ||
value === "test" ||
value === "production"
) {
return value;
}
},
OPENED_COUNTRIES: (value) => {
const array = value.split(",");
if (array.every(validator.isISO31661Alpha2)) {
return array;
}
},
},
});
// -> typeof env = Readonly<{
// ETHEREUM_ADDRESS: string;
// NODE_ENV: "development" | "production" | "test";
// OPENED_COUNTRIES: string[];
// }>
β
Questions
NODE_ENV
for us?
Why not handling Frontend bundlers generally statically replace process.env.NODE_ENV
values at build time, allowing minifiers like terser
to eliminate dead code from production build. Aliasing NODE_ENV
would prevent such optimisations. But if your are working with Node.js, feel free to implement a custom validator for it if you want