node package manager
Love JavaScript? Your insights can make it even better. Take the 2017 JavaScript Ecosystem Survey »


SMConfig v0.2

Build Status Coverage Status Dependency Status devDependency Status

Application configuration module for Node.js.


  • Simple APIs, using ES6 classes
  • Supports multiple environments
  • Automatic environment detection based on hostname
  • Override configuration at runtime with environmental variables
  • Supports loading configuration from JSON, YAML and Hjson documents
  • Offers a plugin for Hapi

This code is licensed under the terms of the BSD (2-clause) license (see

Add to your project

Install from NPM:

npm install --save smconfig

API Guide

Include the module with:

const SMConfig = require('smconfig')

The module exports a class named SMConfig.

Constructor: SMConfig(config, env, options)

let conf = new SMConfig(config, env, options)


  • config: configuration object (read below for description)
  • env: when set, forces a specific environment
  • options: dictionary with advanced options:
    • options.envVarPrefix: prefix for environmental variables (default: APPSETTING_)
    • options.flatten: when true, configuration object is also flatened to "dot notation" (default: true)

The constructor determines the environment, then loads the configuration for the environment and stores it in the object.

The environment is determined by, in order:

  1. The value passed to the env parameter
  2. The process.env.NODE_ENV environmental variable (when launching the application; for example: $ NODE_ENV=production node myapp.js)
  3. The environment that is configured for the hostname (see below)
  4. Fallback to the default environment

The config paramter can either be a JavaScript object or the filename (as string) of a JSON, YAML or Hjson file. The file type is determined by the extension, and supported ones are: *.json, *.yaml, *.yml and *.hjson.

The configuration object must have the following basic structure:

let config = {
    // Default configuration, for all environments
    default: {
        key1: 'value1',
        key2: 'value2'
    // Each subsequent key is the name of the environment;
    // this can be anything you want
    dev: {
        // Custom environments inherit all keys from the default
        // environment, but can be overwritten here
        key1: 'override',
        newkey: 'helloworld'
    production: {
        key1: 'override'
    otherenvironment: {},
    // The hostnames object contains a list of hostnames that are
    // mapped to a specific environment.
    hostnames: {
        // Name of the environment, then list of hostnames
        dev: [
        production: [
            // Can use * as wildcard
            // Can also use RegExp objects

For sample configuration files in JSON, YAML and Hjson, check the documents in the test folder:

When using YAML, you can also use the following types that are not supported by JSON and Hjson: (see documentation for js-yaml for more information)

  • RegExp: !!js/regexp /pattern/gim
  • Functions: !!js/function 'function () {...}'
  • Undefined: !!js/undefined ''

Configuration can also be passed at runtime (and it can override what is defined in the application or in the config files) with environmental variables. These values are prefixed with options.envVarPrefix, which defaults to APPSETTING_; the prefix is then removed, the key is lowercased and converted to camelCase. You can also update a nested object by using a double underscore. For example:

# SMConfig will store 'Passw0rd' for the 'databaseConfiguration' key 
# You can use a custom prefix by changing envVarPrefix, 
# for example to CUSTOMPREFIX_ 
# You can update a nested object, for example oauth.secretKe, using double udnerscores 
$ APPSETTING_OAUTH__SECRET_KEY=Secr3t node myapp.js

When options.flatten is true, as per default value, the configuration data is also "flattened" into a dictionary that uses "dot notation". For example, imagine the following configuration:

// Output when
// options.flatten: false
    "database": {
        "host": "",
        "username": "admin",
        "password": "Passw0rd",
        "ports": [8000, 8001]
    "otherkey": "otherval"
// Output when
// options.flatten: true
    "database": {
        "host": "",
        "credentials": {
            "username": "admin",
            "password": "Passw0rd"
        "ports": [8000, 8001]
    "": "",
    "database.credentials.username": "admin",
    "database.credentials.password": "Passw0rd",
    "database.ports": [8000, 8001],
    "otherkey": "otherval"


// config is an instance of SMConfig
let databasePassword = config.get('databasePassword')
// If options.flatten is true, you can also access "nested" keys
let nested = config.get('database.credentials.password')

Returns the value for the key passed as argument, reading from the configuration for the environment.


// config is an instance of SMConfig
let env = config.environment

The environment property, which is read-only, contains the name of the environment being used by the application.


// config is an instance of SMConfig
let allConfiguration = config.all

The all property, which is read-only, contains all the configuration variables for the current environment.

Hapi plugin

This module offers an optional plugin for Hapi (version 17 or higher required).

To use it, initialize the SMConfig object as normal, then register the plugin with Hapi passing the instance of SMConfig.


const SMConfig = require('smconfig')
const conf = new SMConfig(config, env, options)
await server.register({
    plugin: require('smconfig/plugins/hapi'),
    options: {config: conf}