npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

simplyconfig

v0.4.0

Published

Hierarchical configuration. A replacement to nconf.

Downloads

8

Readme

Hierarchical configuration for modern node.js apps.

Build Status NPM version Project status license Gittip

TL;DR

Replacement to nconf with extra features :

  • loads everything that nconf can load, but also plain json, plain js files, node modules and AMD modules (i.e. you can add comments to your config and lint it with eslint/jshint)
  • clearer API : only one .add(...) function, which deep extends previously added key/values
  • load files from a relative path
  • nconf-like access with customizable separator, or plain associative array access
  • integrated value expansion %extension% in config values
  • integrated .env loading for modern devops
  • integrated support for patterned config (config.json -> config.development.json -> config.development.local.json)

one_does_not

Use case

Config in a modern node app comes from different source :

  • config files, usually an associative array, in JSON and under source control
  • command-line arguments, usually for quick overrides like --debug-level=info
  • Environment variables especially for secrets (passwords, API keys), since they MUST NOT be stored in source control
  • .env file, used by devops as an alternative for passing environment variables. MUST NOT be under source control.

And config data is streamlined like that :

easyconfig

  1. (nothing to do, node does it automatically)
  2. simplyconfig.dotenv.load() (simplyconfig.dotenv being the motdotla/dotenv module, included for your convenience)
  3. simplyconfig does it in 2 ways :
  • automatically by detecting and replacing %MY_ENV_VAR% in config values (can be disabled/customized, see below)
  • manually by calling .add('ENV'). simplyconfig will automatically expand keys, like NODEJS__foo__bar=baz giving the foo.bar : 'baz' key-value entry in config.
  1. .add('ARGV')
  2. .add('config.json', {pattern: 'env+local'}) (see below for this convenient pattern)
  3. var config = require('config'); (see below for an example of what config/index.js should look like)

Usage

Introduction

Using simplyconfig is, as you can guess, easy. Just add key/values, and each one takes precedence over the previous one (deep extend).

var simplyconfig = require('simplyconfig');

var config = simplyconfig
	.create()
	.add({
		env: 'defaults',
		database: {
			host: 'localhost',
			port: 1234
		}
	})
	.add({
		env: 'prod',
		database: {
			host: 'database.foo.io',
		}
	});
	
console.log(config.get()); ->>
	{
		env: 'prod',
		database: {
			host: 'database.foo.io',
			port: 1234
		}
	}

Of course there is syntactic sugar for files :

var simplyconfig = require('simplyconfig');

var config = simplyconfig
	.create()
	.add('../config/config.json')
	.add('../config/config.development.json');
	.add('../config/config.development.local.json');

or even better :

var simplyconfig = require('simplyconfig');

var config = simplyconfig
	.create()
	.add({ NODE_ENV: process.env.NODE_ENV || 'development' });
	.add('../config/config.json', { pattern: 'env+local' });

Real-life example

'use strict';

var simplyconfig = require('simplyconfig');

/** Load .env into process.env
 */
simplyconfig.load({ silent: true });

/** Ensure NODE_ENV is defined
 */
process.env.NODE_ENV = process.env.NODE_ENV || 'development';

/** Load and expose configuration.
 */
module.exports = load();
module.exports.load = load;

/** Load configuration for a given environment.
 *
 * @param  {String} env Asked environment, defaults to process.env.NODE_ENV
 * @return {Object}     nconf-like configuration object
 */
function load(env) {
  var config = simplyconfig.create();

  // explicit early definition of NODE_ENV
  config.add({ NODE_ENV: env || process.env.NODE_ENV || 'development' });

  // files
  config.add('../../config/config.json', { pattern: 'env+local' });

  // env vars
  config.add('ENV');

  // args
  config.add('ARGV');

  return config;
}

detailed usage

immutability

simplyconfig tries hard at immutability, since configuration should not be a dynamic registry modified everywhere in the code.

Hence :

  • a clone of given data is made at insertion. If given object is modified later, it doesn't affect config
  • a clone of the config data is returned on get(). If modified, returned object doesn't affect config

top-level options

Separator for get() is : by default for nconf compatibility. You can change it :

var config =
	easyconf.create({
		separator: '.'
	});

	var x = config.get('foo.bar.baz');

files

Either format are accepted :

  • json config.add('config.json');
  • js config.add('config.js');

Patterned : A convenient way to hierarchize config is the following :

  • config.js <-- safe default
  • config.production.js, config.development.js <-- specialization for a given environment
  • config.development.local.js <-- developper's local changes, this file should be in .gitignore Each file taking precedence over previous one.

This patter is integrated in simplyconfig : config.add('config.js', { pattern: 'env+local' });

For reading the current environment, simplyconfig uses :

var env = this.get('NODE_ENV') || process.env.NODE_ENV || 'development';

env

config.add('ENV'); will :

  1. load all env vars at the root of the config (or under options.root if provided, see below).
  2. expand env vars with key matching a pattern, like this : NODEJS__foo__bar being also added as foo.bar
  3. values are expanded as usual

Default options :

{
	whitelist: null,  <-- an array of restricted env vars to pick
	root: '',         <-- where env vars will be added in the config
	prefix: 'NODEJS', <-- prefix for deep env vars
	separator: '__'   <-- separator for deep env vars
}

args

config.add('ARGV'); will : 1 load and expand command-line arguments exactly like nconf does (using optimist)

  1. values are expanded as usual

TOREVIEW

  • warnings for empty paths
  • get/set with options