Configuration of JavaScript (Node.js) Applications
Any modern Node.js application requires flexible management of settings: database parameters, API keys, ports, logging levels. Proper configuration is not just about reading files; it's a whole culture of security, testability, and portability. In this article, we will review the key libraries and approaches that will help you organize configuration in JavaScript (Node.js) projects.
Why are separate configuration tools needed?
Manual management via process.env or JSON files quickly leads to chaos. The main problems include:
- Mixing secrets (passwords) with code — a security risk if committed to a repository.
- Lack of validation — a typo in a variable name can cause a hard-to-find error.
- Difficulty supporting different environments (dev, staging, production).
1. dotenv — the standard for environment variables
The most popular library (over 25 million downloads per week). It loads variables from a .env file into process.env. Ideal for local development.
Installation and basic setup
npm install dotenvCreate a .env file in the project root:
PORT=3000DB_HOST=localhostDB_USER=adminDB_PASS=secret123Include it at the very beginning of your main file (e.g., app.js):
require('dotenv').config();
const express = require('express');const app = express();
app.listen(process.env.PORT, () => { console.log(`Server running on port ${process.env.PORT}`);});Important: never commit .env to Git! Add it to .gitignore. Instead, create a .env.example with a template.
Custom path and multiple files
// Loading from a specific pathrequire('dotenv').config({ path: '/custom/path/.env' });
// Support for multiple environmentsif (process.env.NODE_ENV === 'production') { require('dotenv').config({ path: '.env.production' });} else { require('dotenv').config({ path: '.env.development' });}2. config — hierarchical configuration
The config library (from the creators of node-config) offers a powerful system with default settings, overrides for environments, and support for different formats (JSON, YAML, JS).
Folder structure
config/ default.json # Base settings production.json # Production overrides development.json # Local overrides custom-environment-variables.json # Mapping to process.envExample default.json:
{ "server": { "port": 3000, "host": "localhost" }, "db": { "host": "localhost", "port": 5432, "name": "myapp" }}Usage in code:
const config = require('config');
const dbConfig = config.get('db');console.log(`Connecting to ${dbConfig.host}:${dbConfig.port}/${dbConfig.name}`);Feature: automatically selects the file based on NODE_ENV. If NODE_ENV=production, it merges default.json + production.json.
3. nconf — flexible hierarchy of sources
nconf allows you to combine multiple configuration sources with priorities: command-line arguments → environment variables → files → default values.
const nconf = require('nconf');
// Define the hierarchy (top — highest priority)nconf .argv() // Command-line arguments .env('__') // Environment variables (separator __ for nesting) .file({ file: 'config.json' }) // Configuration file