Layered configuration loader supporting JSON files and environment variables with dot-path access. Precedence: environment variables override JSON file values, which override defaults.
npm install @ferrow/config-loaderimport { ConfigLoader } from 'config-loader';
// Layer 1: defaults (lowest)
// Layer 2: JSON file (app.json)
// Layer 3: env vars (highest, with APP_ prefix)
const config = new ConfigLoader({
defaults: {
port: 3000,
database: { host: 'localhost', port: 5432 }
},
filePath: './app.json',
envPrefix: 'APP_'
});
const port = config.get('port'); // from env, JSON file, or default
const dbHost = config.get('database.host');Options:
defaults: Default values (Record<string, any>, optional)filePath: Path to JSON config file (string, optional; missing file is silently ignored)envPrefix: Prefix for env vars to load (string, optional; e.g., 'APP_')
Precedence (highest to lowest):
- Environment variables (if prefix matches)
- JSON file values
- Defaults
Get a value using dot-path notation (e.g., 'database.host').
config.get('database.host'); // returns undefined if not found
config.get('database.host', 'localhost'); // returns default if not foundGet multiple values. Throws if any key is missing.
const { db_host, db_port } = config.required(['database.host', 'database.port']);
// Throws: "Missing required configuration keys: database.port"Get entire configuration as a plain object.
Variables are mapped using a prefix and underscore-to-dot conversion:
| Env Var | Prefix | Becomes |
|---|---|---|
APP_PORT |
APP_ |
port |
APP_DB_HOST |
APP_ |
db.host |
APP_DB_POOL_MAX |
APP_ |
db.pool.max |
Variable names are lowercased. Values are coerced:
'true'→true(boolean)'false'→false(boolean)- Numeric strings → numbers
- Others → strings as-is
const config = new ConfigLoader(); // All env vars loaded, lowercased
config.get('node_env'); // from NODE_ENV env var// app.json
{
"port": 3000,
"database": {
"host": "localhost",
"pool": { "max": 10 }
}
}process.env.APP_PORT = '8080';
process.env.APP_DB_POOL_MAX = '20';
const config = new ConfigLoader({
defaults: { debug: false },
filePath: './app.json',
envPrefix: 'APP_'
});
config.get('port'); // 8080 (from env, overrides 3000 from file)
config.get('database.host'); // 'localhost' (from file, no env override)
config.get('database.pool.max'); // 20 (from env, overrides 10 from file)
config.get('debug'); // false (from defaults)- Missing JSON files are silently ignored; use
filePathonly for optional config files. - Returned values are mutable; do not modify them if immutability is required.
- No circular reference detection for defaults or file content.
- Environment variable values are strings until coerced; custom types require manual conversion after
.get(). - No hot-reload; configuration is read once at instantiation.
Sponsored by Ferrow
Part of the ferrow-toolkit collection · Sponsored by Ferrow