config-plus
v0.1.1
Published
Merge 2 configurations, merge configuration with environment variables
Maintainers
Readme
config-plus
A lightweight TypeScript library for merging configuration from multiple sources:
- Default Configuration
- Environment Configuration (SIT, UAT, PRD)
- Environment Variables (process.env)
Configuration is merged in the following order:
Default Configuration
│
▼
Environment Configuration (SIT, UAT, PRD)
│
▼
Environment Variables (process.env)
│
▼
Final ConfigurationEnvironment variables always have the highest priority
Features
- Recursive config merging
- Environment overrides (SIT, UAT, PRD)
- Environment variables overrides (process.env)
Examples:
REST API
- sql-modular-sample: REST API with MySQL.
- mongo-simple-modular-sample: REST API with MongoDB.
Import Data
- import-sample: import a fix-length file to MySql.
- import-csv-sample: import a CSV file to MySql.
Export Data
- postgres-export-sample: export data from Postgres to CSV.
- mssql-export-sample: export data from MS SQL to CSV.
- mysql-export-sample: export data from MySql to CSV.
Message Queue
- rabbitmq-sample: An example to consume message from rabbitmq.
- activemq-sample: An example to consume message from activemq.
- nats-sample: An example to consume message from nats.
Strengths
- 🚀 Zero dependencies
- 📦 Lightweight and fast
- 🔷 Written in TypeScript
- 🔒 Strongly typed API
- 🔄 Deep object merge
- ✅ Automatic parsing of:
- string
- number
- boolean
- array (JSON)
- 📋 Array override support
Installation
npm install config-plusor
yarn add config-plusWhy?
Most applications need configuration from multiple sources.
For example:
- Default configuration
export const config = {
server: {
port: 8000,
host: "localhost",
},
database: {
host: "localhost",
port: 5432,
},
}- UAT overrides and PRD overrides for the configuration
export const environments = {
uat: {
server: {
port: 8080,
},
},
prd: {
server: {
port: 80,
},
database: {
port: 5431,
},
},
}- Environment variables
SERVER_PORT=443
DATABASE_HOST=db.company.comThe library automatically combines all of them into a single configuration object.
Quick Start
import { merge } from "config-plus"
export const config = {
server: {
port: 8000,
host: "localhost",
},
database: {
host: "localhost",
port: 5432,
},
}
// SIT overrides and PRD overrides for the configuration
export const environments = {
uat: {
server: {
port: 8080,
},
},
prd: {
server: {
port: 80,
},
database: {
port: 5431,
},
},
}
const cfg = merge(config, process.env, environments, "prd")
when
SERVER_PORT=443
DATABASE_HOST=db.company.comResult:
{
server: {
host: "localhost",
port: 443
},
database: {
host: "db.company.com",
port: 5431
}
}Architecture
merge()
│
├── mergeEnvironments()
│
└── mergeEnv()
│
▼
mergeWithPath()Type handling
This is one of the strongest parts.
It automatically converts environment variables based on the existing property's type.
Strings
"localhost"
↓
HOST="google.com"
↓
"google.com"Numbers
8080
↓
PORT=3000
↓
3000with validation.
Boolean
false
↓
SSL=true
↓
trueArrays
Allows
STATUS=["A","B","C"]using JSON parsing.
Many libraries don't support arrays.
Objects
Recursive
db.user
↓
DB_USERNaming convention
Environment names become
db.host
↓
DB_HOSTand
cache.redis.timeout
↓
CACHE_REDIS_TIMEOUTThis is an industry-standard convention
Configuration acts as schema
Instead of
{
type: Number,
default: 8080
}simply write
port: 8080The runtime infers
numberVery elegant.
No decorators
Supported Types
Current implementation supports
- string
- number
- boolean
- object
- array
Not supported
- ❌ bigint
- ❌ Date
- ❌ Map
- ❌ Set
- ❌ enum
- ❌ null override
- ❌ undefined override
API
merge()
merge(
config: { [key: string]: any },
env: ProcessEnv,
environments?: { [key: string]: { [key: string]: any } },
environmentName?: string,
logError?: (msg: string) => void,
logInfo?: (msg: string) => void,
): { [key: string]: any };Merges:
- default configuration
- environment configuration (SIT, UAT, PRD)
- process environment variables
Example
const config = merge(defaults, process.env, environments, "uat")mergeEnvironments()
mergeEnvironments(config, environmentConfig)Deep merges an environment configuration into the default configuration.
Example
mergeEnvironments(defaultConfig, productionConfig);mergeEnv()
mergeEnv(config, process.env)Overrides configuration values using environment variables.
mergeWithPath()
Internal recursive merge function.
Normally you should call merge() instead.
Environment Variable Mapping
Nested properties are converted into uppercase environment variables.
Configuration
{
server:{
port:8080
}
}becomes
SERVER_PORTMore examples
| Configuration | Environment Variable |
| -------------------- | -------------------- |
| database.host | DATABASE_HOST |
| database.port | DATABASE_PORT |
| database.pool.size | DATABASE_POOL_SIZE |
| logging.level | LOGGING_LEVEL |
Supported Types
String
{
host:"localhost"
}HOST=myserver↓
host = "myserver"Number
{
port:8080
}PORT=9090↓
port = 9090Boolean
{
ssl:false
}SSL=true↓
ssl = trueOnly the literal value "true" enables the option.
Arrays
Arrays must be valid JSON.
SERVERS=["a","b","c"]↓
servers = [
"a",
"b",
"c"
]Nested Objects
Nested objects are merged recursively.
Default
{
database:{
host:"localhost",
port:5432
}
}Override
{
database:{
host:"production-db"
}
}Result
{
database:{
host:"production-db",
port:5432
}
}Example
- sql-modular-sample: REST API example with MySQL.
- sql-simple-modular-sample: REST API example with Posgres.
- mongo-simple-modular-sample: REST API example with Mongo.
Quick example:
const defaults = {
server: {
host: "localhost",
port: 8080
},
database: {
host: "localhost",
port: 5432
}
};
const environments = {
uat: {
server: {
port: 80
}
}
};
process.env.SERVER_HOST = "0.0.0.0";
process.env.DATABASE_HOST = "db.company.com";
const config = merge(defaults, process.env, environments, "uat");Result
{
server: {
host: "0.0.0.0",
port: 80
},
database: {
host: "db.company.com",
port: 5432
}
}Best Practices
- Keep default values in your configuration file.
- Store secrets in environment variables.
- Use environment-specific configuration for deployment differences.
- Avoid hardcoding credentials.
- Commit only default configuration to source control.
Limitations
Current implementation does not support:
- custom value parsers
- enum parsing
- Date objects
- Map / Set
- immutable merging
These features may be added in future versions.
Comparison with popular libraries
Why config-plus
Many configuration libraries include features such as file loading, validation, schemas, plugins, and dependency injection. While powerful, they can be unnecessary for smaller projects or reusable libraries.
config-plus focuses on one job:
- merging configuration objects,
- applying environment-specific overrides,
- overriding values from process.env
The result is a tiny, dependency-free utility that is easy to understand, easy to maintain, and suitable for applications, libraries, and frameworks.
Recommended Usage
This library is best suited for:
- Microservices
- REST APIs
- Batch jobs
- Internal backend applications
- Docker/Kubernates deployments
License
MIT
