Environment variables. They make it easy to juggle between your local development, testing, staging, UAT, production or whatever other environments may have crept into your work flow. Passing around variables is easy enough but when you have more than a couple it can be a pain to remember them all. Instead of passing variables into your scripts individually, env-cmd
makes it easy to group variables into an environment or “env” (I like to pronounce it like “envy”) file and pass them all to your script.
🐊 Alligator.io recommends ⤵
Learn Node, a video course by Wes Bos
ⓘ About this affiliate link
Safety First
It’s worth noting that while you may feel compelled to add environment and configuration files to your version control system, it’s generally considered a bad practice, since these files probably contain sensitive information.
To make sure you don’t accidentally add a file to your repository with logic credentials or keys, be sure to add the file to your .gitignore
.
Getting Started
To get started with env-cmd
, simply add it to your project with npm
or yarn
:
# via npm $ npm install env-cmd # via yarn $ yarn add env-cmd
We can also create a basic environment file. Don’t worry it will append to your existing .env
file if one exists:
echo 'reptile=alligator\ngreen=#008f68\nyellow=#fae042' >> .env
And for good measure, we’ll create a script named gator.js
to log our variables to the console:
console.log('NODE_ENV:', process.env.NODE_ENV); console.log('Reptile:', process.env.reptile); console.log('Green:', process.env.green); console.log('Yellow:', process.env.yellow);
Basic Usage
The env-cmd
package installs an executable script named env-cmd
which can be called before your scripts to easily load environment variables from an external file.
Depending on your setup, you can reference env-cmd
in a few different ways. The easiest and most compatible across package managers, is to setup a script within your package.json
file:
{ "scripts": { "gator": "env-cmd .env node gator.js" } }
The script expects an environment file as the first parameter and the command you would like to run after that.
If you would prefer to use env-cmd
directly from the command-line, you can call it directly from node_modules
:
$ ./node_modules/.bin/env-cmd .env node gator.js
If you’re using a more recent npm
version that supports npx, you can use that instead:
$ npx env-cmd .env node gator.js
And if yarn
is your bag, you can leverage it’s run
command:
$ yarn run env-cmd .env node gator.js
Regardless of how you choose to run the script, env-cmd
will load up our .env
file and our test script will report back the variables.
You may have noticed that the “Environment” value came back as undefined
. That’s because we don’t have NODE_ENV
defined in our .env
file. Because env-cmd
plays nice with the environment variables that are already set, we can still opt to pass in NODE_ENV
before calling env-cmd
:
$ NODE_ENV=development npx env-cmd .env node gator.js
Supported File Formats
As mentioned, the first argument passed to env-cmd
is the path and/or filename of your environment file. Typically, you would name the file .env
and have it in either your project’s root or your home directory.
env-cmd
supports files in either of the aforementioned locations, or you can simply reference the absolute path to the file.
Regardless of how you reference it, you have a wide variety of file formats available to store your environment variables.
JSON File
{ "reptile": "alligator", "green": "#008f68", "yellow": "#fae042" }
JavaScript
module.exports = { reptile: 'alligator', green: '#008f68', yellow: '#fae042' };
INI File
reptile=alligator green-#008f68 yellow=#fae042
RC File
The rc
file format is special because it allows you to define multiple environments in a single JSON file and reference the environment by name instead of by file.
The “runcom” file is also special in that is must be named .env-cmdrc
and present in the root of your project.
{ "development": { "NODE_ENV": "development", "reptile": "alligator", "green": "#008f68", "yellow": "#fae042", "otherVar1": 1 }, "staging": { "NODE_ENV": "staging", "reptile": "crocodile", "green": "#6db65b", "yellow": "#efbb35", "otherVar2": 2 }, "production": { "NODE_ENV": "production", "reptile": "turtle", "green": "#4aae9b", "yellow": "#dfa612", "otherVar3": 3 } }
Then you can reference a single environment as such:
$ npx env-cmd development node gator.js
You can even reference multiple environments, which will merge together each of the environment’s variables, with the last environment taking precedence if there are overlapping variables:
$ npx env-cmd development,staging,production node gator.js
By specifying all three of our environments, each of the otherVar
values will be set, with the rest of the variables being sourced from the final environment listed, production
.
Graceful Fallbacks
Out of the box, env-cmd
won’t put up much of a fight if the environment file you specify doesn’t exist. In that scenario you just won’t have access to any of the expected variables so you should be mindful of this when coding.
If you would prefer, env-cmd
can attempt to load an .env
file from the root of your project in situations when the specified file doesn’t exist. To do so, pass in the --fallback
flag:
$ npx env-cmd .missing-env --fallback node gator.js
Respecting Your Environment
Sometimes, you may want to favor the variables already set in the environment, instead of using the values in your .env
file. To respect the existing environment variables, pass env-cmd
the --no-override
flag:
$ NODE_ENV=production npx env-cmd .env --no-override node gator.js
In the above example, even if the .env
file has the NODE_ENV
variable defined, the value of NODE_ENV
will remain as production
.