Managing Multi-Environment Configurations in Node.js with a Single Configuration File
In the past, when I was working on Node.js projects that could run under different environment settings (e.g., local, develop, staging, production), a typical pattern was to create multiple configuration files per environment. For example, a project with three environments: local
, develop,
and production
, would need three configuration files:
Each of these files defines an object with a similar structure but different configuration values for every environment. For example, the config.local.json
might define the hosts for the local API server and the local database connection string:
Then, a config.js
module could use a simple logic that loads the correct configuration file for the target environment, for example, by checking an environment variable such as NODE_ENV
:
However, as the project and the team working on it grew, these configuration files often came out of sync. For example, while working on a new feature, a developer could add a new field to a local
configuration and forget to add it to other configuration files and break other environments.
I've identified the following drawbacks when using this pattern:
- No validation for missing keys between environments.
- Risk of having out-of-sync configuration files.
- No way to define default or fallback values.
- Difficulty seeing all the configuration values per environment per key in one place.
- Difficulty creating new environments
Therefore, I created a small utility that improves multi-environment configuration management by storing all configurations in a single JSON file to solve these problems.
Solution - single-config
Single-Config is a small npm package that solves the problems described above. It lets you define a single configuration file for all environments. It can also generate types for the configuration files using TypeScript.
Continuing the previous example, using single-config, you can define a single configuration file config.json
:
After installing single-config and running the buildconfig
command:
It will generate a config.js
module exporting an object with all the properties resolved to the "local" environment:
The following diagram depicts the build logic: