In this post I will walk you through How I manage and organize configuration inside my Node.js project.
Configuration defines the state of your app, the better it is organized the easier will be managing it.
I recommend you to go through this page to get better understanding of why we should use environment aware, secure and hierarchical configurations.
To manage configurations in my node.js project I use two packages: node-config and dotenv
dotenv
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env
Usage
It is super simple to use app. You just create a .env
file in your root directory of the app. (At the same level as your package.json)
.env
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
Now, to inject these values in process.env
, and to use in your application, require and configure dotenv
.
Most of the time it is done in your app.js at the top
const express = require('express');
const app = express();
const router = express.Router();
// load environment config variables
require('dotenv').config();
That's it?
Clearly not! This has made managing environment variables better but what about other app configurations?
config
Node-config organizes hierarchical configurations for your app deployments.
It lets you define a set of default parameters, and extend them for different deployment environments (development, qa, staging, production, etc.)
Usage
To use this package, you create a config directory in your root directory of the project.
For your each environment you create separate files.
node_modules
src
config
- production.json
- development.json
- default.json
- custom-environment-variables.json
- test.json
.env
package.json
I like to put my config
directory inside source of the project. config
can be placed anywhere in the project but the should be defined as environment varialbe.
NODE_CONFIG_DIR=./src/config
Now the package will look for configuration files insidesrc/config
.
More about config
The package first looks for the NODE_CONFIG_DIR
environment variable to see where from it should load the configuration files.
Now, it looks for NODE_ENV
to inject appropriate configuration as per the defined environment.
While loading configurations, it first loads configs from default.json
and then overrides and extends based on defined configs inside loaded environment configs.
Using config
with dotenv
There is special file you can create inside config folder custom-environment-variables.json
.
config
package gives you option to inject environment variables from process.env
.
So that you have only one package to manage all your configuration across whole app.
If you have defined environment variables in .env
file as,
OTP_EXPIREY=5m
ACCESS_TOKEN_EXPIREY=2m
You can inject these env in config package as below inside your custom-environment-variable.json
file.
{
"otp_expire": "OTP_EXPIRY",
"access_token_expiry": "ACCESS_TOKEN_EXPIREY"
}
Now to get any config vairable, you have one source that is config
.
const { otp_expiry, access_token_expiry, prod_claims } = require('config')
Bonus
Configuration files should be easily readable. I personally find json
files less readable because of two things: no comment support, braces and double quotes everywhere
Luckily config
support other file formats than json.
I use yaml
files for managing my configurations.
They support comments and also look very clean.
To check for a working example please have a look on this repo .