What is env-var?
The env-var npm package is a utility for accessing and validating environment variables in Node.js applications. It provides a simple and consistent API for retrieving environment variables, ensuring they meet specified criteria, and handling default values.
What are env-var's main functionalities?
Accessing Environment Variables
This feature allows you to access environment variables and convert them to the desired type. In this example, the 'PORT' environment variable is retrieved and converted to a positive integer.
const env = require('env-var');
const port = env.get('PORT').asIntPositive();
console.log(`Server running on port: ${port}`);
Default Values
This feature allows you to specify default values for environment variables. If the 'HOST' environment variable is not set, it defaults to 'localhost'.
const env = require('env-var');
const host = env.get('HOST').default('localhost').asString();
console.log(`Server running on host: ${host}`);
Validation
This feature ensures that certain environment variables are set and meet specified criteria. In this example, the 'API_KEY' environment variable is required and must be a string.
const env = require('env-var');
const apiKey = env.get('API_KEY').required().asString();
console.log(`API Key: ${apiKey}`);
Custom Validators
This feature allows you to define custom validation logic for environment variables. In this example, the 'CUSTOM_VAR' environment variable must start with 'custom-'.
const env = require('env-var');
const customValidator = (value) => value.startsWith('custom-');
const customVar = env.get('CUSTOM_VAR').required().asString().validate(customValidator);
console.log(`Custom Var: ${customVar}`);
Other packages similar to env-var
dotenv
dotenv is a popular package for loading environment variables from a .env file into process.env. It does not provide validation or type conversion features like env-var, but it is widely used for managing environment variables in development.
joi
joi is a powerful schema description language and data validator for JavaScript. While it is not specifically designed for environment variables, it can be used to validate them. It offers more complex validation rules compared to env-var.
convict
convict is a configuration management tool for Node.js that allows you to define a schema for your configuration, including environment variables. It provides validation and default values, similar to env-var, but also supports nested configurations and different configuration sources.
env-var
An elegant solution for loading environment variables in node.js.
Install
npm install env-var --save
Example
In the example below we read the environment variable PARALLEL_LIMIT, ensure
it is set (required), and parse it to an integer.
var PARALLEL_LIMIT = env('PARALLEL_LIMIT').required().asPositiveInt();
Here's what each piece of this code means:
- If PARALLEL_LIMIT is not set required() will raise an exception.
- If it is set, but not a positive integer asPositiveInt() will raise an
exception.
- If #1 and #2 do not raise an exception, the number will be returned as a
valid JavaScript number type.
Overview
Over time it became apparent that parsing environment variables is a
repetitive task, and testing code that relies on them is cumbersome unless
using an inversion of control system for declaring modules so we can inject a
fake process.env.
Take this example:
var assert = require('assert');
assert.notEqual(
process.env.MAX_BATCH_SIZE,
undefined,
'MAX_BATCH_SIZE environment variable must be set'
);
var MAX_BATCH_SIZE = parseInt(process.env.MAX_BATCH_SIZE, 10);
assert(
typeof MAX_BATCH_SIZE === 'number' && !isNaN(MAX_BATCH_SIZE),
'MAX_BATCH_SIZE env var must be a valid number'
);
With env-var the example above can be written cleanly:
var env = require('env-var');
var MAX_BATCH_SIZE = env('MAX_BATCH_SIZE').required().asInt();
When it comes to testing code that relies on environment variables this is also
great since you can mock out env-var using proxyquire to easily alter
results returned without having to share state via process.env. A
demonstration of this is at the bottom of the README.
API
The API is just a single function that's exposed, let's call it env.
env([varname, [default]])
You can call this function 3 different ways:
- Calling without arguments will return the entire process.env Object.
- Calling with varname will return a variable instance with utilities for
parsing variables and is detailed below.
- Calling with varname, and default will return the value for varname
set on process.env, or if the variable is not set default run through the
variable instance functions as though it was set on process.env.
variable
A returned variable has the following functions defined for parsing to the
required format.
required()
Ensure the variable is set on process.env, if not an exception will be thrown.
asInt()
Attempt to parse the variable to an integer. Throws an exception if parsing
fails. This is a strict check, meaning that if the process.env value is 1.2,
an exception will be raised rather than rounding up/down.
asPositiveInt()
Performs the same task as asInt(), but also verifies that the number is
positive (greater than or equal to zero).
asNegativeInt()
Performs the same task as asInt(), but also verifies that the number is
negative (less than zero).
asFloat()
Attempt to parse the variable to a float. Throws an exception if parsing fails.
asString()
Return the variable value as a String. Throws an exception if value is not a
String. It's highly unlikely that a variable will not be a String since all
process.env entries you set in bash are Strings by default.
asBool()
Attempt to parse the variable to a Boolean. Throws an exception if parsing
fails. The var must be set to either "true", "false" (upper or lowercase),
0 or 1 to succeed.
asStrictBool()
Attempt to parse the variable to a Boolean. Throws an exception if parsing
fails. The var must be set to either "true" or "false" (upper or lowercase) to
succeed.
asJson()
Attempt to parse the variable to a JSON Object. Throws an exception if parsing
fails.
Example
var env = require('env-var');
process.env.STRING = 'test';
process.env.INTEGER = '12';
process.env.BOOL = 'false';
process.env.JSON = '{"key":"value"}';
var allVars = env();
var stringVar = env('STRING').required().asString();
var intVar = env('INTEGER').asInt();
var floatVar = env('FLOAT', '23.2').asFloat();
var boolVar = env('BOOL').required().asBool();
var jsonVar = env('JSON').asJson();
Testing Overview
When testing code that relies on environment variables sometimes we need to
mock out/set the environment variables. Having calls to process.env strewn
throughout a test is and can get confusing and modifies global state (not good).
It's better to use env-var and its built-in mock()
function. Using mock()
will allow you to create a mocked version of env-var which will use a literal
object instead of using process.env. You can use this mocked version with
something like Proxyquire. For example:
var env = require('env-var');
exports.concat = function (envVarToGet) {
return envVarToGet + ' ' + env(envVarToGet).asString();
};
var expect = require('chai').expect;
var proxyquire = require('proxyquire');
var env = require('env-var');
describe('concat.js', function () {
var mod;
beforeEach(function () {
mod = proxyquire('./concat', {
'env-var': env.mock({
HELLO: 'WORLD'
})
});
});
describe('#concat', function () {
it('should combine our var name and returned value', function () {
expect(mod.concat('HELLO')).to.equal('HELLO WORLD');
});
});
});
TypeScript
To use with TypeScript, just import it like this:
import env from 'get-env';
const stringVar = env('STRING').required().asString();
Contributors