A small utility for checking process.env based on a .env.template file in node.js. You can use it to make sure all your env variables are set before running your application, and optionally ensure they're of the right types too.
Simply install with npm or yarn. validate-env is available on the NPM registry and on GitHub Packages.
npm install @efstajas/validate-env
or
yarn add @efstajas/validate-env
First, create your .env.template
file. This file contains all the .env variables you want to validate for. While you should never commit a .env file, committing the .env.template makes a lot of sense β everyone working on your project can see immediately what values they need, and validation will work as expected on any client. An example .env.template
might look something like this:
FOO=string
BAR=number
FOOBAR=array
FOOBARFOO=boolean?
This .env.template
means you expect all the variables FOO, BAR, and FOOBAR to exist. The ?
at the end of the FOOBARFOO variable's type means that it's an optional value β so, validation won't fail if it's not set, but if it is, it must be of type boolean
. As you can see, after the =, you can specify a type for that given variable:
number
means your variable must be numeric, meaning it can be something like1
or004
or even6e+2
.array
means your variable must be a valid JSON array, like["foo", 123]
. Please note it must be valid JSON, meaning strings are to be double-quoted.boolean
means your variable must be either'true'
or'false'
string
means your variable must be a valid string. In practice, any value will pass this test, because .env variables are always strings.
π‘You can put comments in your env template by using #
. Great for annotations or sharing default values!
To run the test, simply import the main function, and pass it your .env.template
file path. It returns a Promise that will resolve to a ValidatorResult
.
import validateEnv from '@efstajas/validate-env'
validateEnv('./path/to/your/.env.template').then((r) => {
if (r.result === 'pass') {
// Your .env is valid!
}
if (r.result === 'fail') {
// Something is wrong in your .env
}
}).catch((e) => {
/*
Something went wrong while validating β
maybe we couldn't open the file, or the
template itself is invalid.
*/
console.error(e)
})
The ValidatorResult
contains either a SuccessPayload
like { result: 'pass' }
, or a FailedPayload
which includes more info about what exactly failed:
validateEnv('./path/to/your/.env.template').then((r) => {
if (r.result === 'fail') {
const { failedVar } = r
const {
name,
expectedType
} = failedVar
switch (failedVar.reason) {
case 'MISSING':
// Variable is missing from .env
case 'WRONG_TYPE':
// Variable is present, but doesn't match expected type
}
}
})
Usually, you would want to validate your .env
at the very beginning of your app, and if it fails, don't even initialize it. The best way to achieve this is to just wrap your initialization routine into a function, and then call it only if the validateEnv
result indicates that your .env
is valid. For an express application, it could look something like this:
// Use dotenv to load .env file into process.env
import * as dotenv from 'dotenv'
dotenv.config()
import express from 'express'
import validateEnv from '@efstajas/validate-env'
const initializeApplication = () => {
const server = express.server
// Register routes, middleware etc.
server.listen(8000)
}
validateEnv('./.env.template').then((r) => {
if (r.result === 'pass') {
initializeApplication()
}
})
By default, validate-env
prints warnings or a success message to the console automatically after validation. If you want to handle logs by yourself, you can disable this behavior by passing the silent
option:
validateEnv('./.env.template', { silent: true }).then((r) => {
if (r.result === 'fail') {
const { failedVar } = r
const {
name,
expectedType
} = failedVar
switch (failedVar.reason) {
case 'MISSING':
console.log(`Variable ${name} is missing in .env. Expected type: ${expectedType}`)
break
case 'WRONG_TYPE':
console.log(`Variable ${name} isn't of expected type ${expectedType}.`)
break
}
return
}
console.log('.env is valid π')
initializeApplication()
}
})