/ javascript

Lookenv

A couple of weeks ago I released lookenv, this is a post about the idea behind it and how to make it work.

The Problem

There are two scenarios where I see that env vars validation is fundamental.

Anything that uses .env
One of the main difference from dotenv, is that your .env file shouldn't be commited to the repository.

Take for instance this repository: RodrigoEspinosa/tito-tickets

This one uses lookenv to ensure that all the required env vars are a present before starting the service, but also it establishes one default.

Anything that uses process.env
This is actually very much related with the previous one, but, I'm working on a project that uses process.env heavily for all the configuration, and this variables are injected by Docker.

However, they might be not even present in some builds. That's why making sure they are before intializing each service is so important.


Introducing: lookenv

Set rules for the environment variables in your project.

NPM Version Build Status Downloads Stats

lookenv can check if all the variables you need are present before starting your app. It also can set defaults for those variables that are not present.

lookenv

Installation

npm install lookenv --save

# Or with yarn
yarn add lookenv

Usage

I wanted to make it as simple as possible to use. So, there's a super basic cli exposed in the package to load the variables and apply the rules before starting your app.

The script will spawn a process for the app or anything you specified, with all the variables in place. This includes the defaults.

This means that, lookenv -- node index.js will apply the rules in the config file (it uses cosmiconfig) and spawn a node process, but it can be anything really.

Configuration

Setting the configuration is easy. You can create a lookenv.config.js, .lookenvrc or inside your package.json. As default, lookenv will look for your script in the cwd (current working directory) which is generally the project root when starting your app. But that can be specified passing a path flag to the script. Like lookenv --path=/path/to/lookenv/config -- my-script.

An example config could be:

module.exports = {
    MY_ENV_VAR: {
        required: true
    },
    MY_SND_ENV_VAR: {
        default: 'Testing'
    }
}

Or, inside a package.json, the equivalent version should be:

{
    "scripts": {
        "start": "lookenv -- node index.js"
    },
    "lookenv": {
        "MY_ENV_VAR": {
            "required": true
        },
        "MY_SDN_ENV_VAR": {
            "default:" "Testing"
        }
    }
}

With dotenv

When running lookenv, you can pass a dotenv flag (like lookenv --dotenv -- my-script) to load dotenv before applying the rules for the env vars.

Which means that lookenv is fully compatible with dotenv. And it's actually a valid way to run dotenv via a cli, and not inside your app entry point.

You can also, pass the location of the .env file via the cli with lookenv --dotenv=/path/to/the/env/file.

Next step

There are a few things I want to do next, but I'll leave the more ambitious ones after hearing if someone is actually using this. Those involve mechanisms to dynamically set / read env vars and reload apps.

The immediate next step is to add proper validations with joi.

For the next lookenv release, you will be able to do this kind of validations:

// lookenv.config.js

const Joi = require('joi')

module.exports = Joi.object().shape({
    MY_ENV_VAR: Joi.string().required()
})

Among all the other fancy validations, which goes from validating a number or port to a complex pattern and juxtaposed attributes.


All the logo credits goes to my friend Guillermo Cura. Thank you, Guille!

In case you didn't notice, it uses the same colors as this blog :wink:.

lookenv


Credits of the cover pictures goes, once again, to my photographer girlfriend Celeste Korol. This time, with a probably unnecessary filter to blend with the background.