nconf: hierarchical configuration for Node.js, ordered by attachment
Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging.
At a glance
- What is it?
- nconf is a key-value configuration store for Node.js that merges command-line arguments, environment variables, files and defaults in the order you attach them. It is small, MIT licensed, and still at a 1.0.0 beta after years of production use.
- Who is it for?
- Adopt nconf if you want a small, MIT licensed store where the precedence of argv, env and files is explicit in code and readable in one screen. Do not adopt it if you need validation schemas, typed parsing or hot reload; nconf gives you required() and nothing else.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 68 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The problem nconf solves: configuration precedence you can read
A Node.js service usually ends up reading configuration from three places: flags passed by whoever starts the process, environment variables injected by the platform, and a file checked into the repository or mounted at deploy time. Writing that resolution by hand produces the same bug every time, because each source is consulted in a different place and the precedence is implicit.
nconf makes the precedence explicit. The README states the rule directly: "The order in which you attach these configuration sources determines their priority in the hierarchy." Sources are attached with nconf.argv(), nconf.env(), nconf.file(), nconf.defaults() and nconf.overrides(), and the first store that has a value for a key wins. Keys are namespaced with a colon, so database:host and database:port collapse into a nested object when you call get('database').
The audience is Node.js developers running services that need a different configuration per environment without a configuration framework. The package ships as a single main module, ./lib/nconf, with two runtime dependencies, ini and yargs, which is a small footprint for something loaded at process start.
How the provider, stores and colon keys fit together
The top level of the module is an instance of nconf.Provider, and the README describes that object as abstracting the rest behind a simple API. A provider holds an ordered list of stores. Each store is a storage engine with a name and a type, and add(name, options) appends one, use(name, options) replaces an existing one, and remove(name) takes one out of the lookup chain entirely.
Lookups walk the chain in order. get() returns the first value found, any() takes a list of key names and returns the first truthy one, which is how you support both NODEJS_PORT and PORT without branching in application code. The Memory engine is the base class for the built-in engines and keeps a nested JSON representation of the configuration; the README notes that get(), set(), clear() and reset() are synchronous on it because only an in-memory object is involved.
Files are the part with the most options. A file store can be given a path, a custom name, or a name plus a dir and search: true to look for config.json starting from a base directory. The README adds a constraint worth reading twice: a custom key must be supplied for the hierarchy to work if multiple files are used. Attach several files without names and the ordering you intended is not the ordering you get.
Installing nconf from npm and running the README example
nconf is published to npm as nconf. The package.json declares engines of node >= 0.4.0, which is a historical floor rather than a recommendation, and lists yargs ^17.0.0 and ini ^2.0.0 as dependencies. Install it into a project as a normal dependency:
npm install nconfThe README's sample script attaches three sources in order, then sets and reads values. Save this as sample.js and run it:
var nconf = require('nconf');
nconf.argv()
.env()
.file({ file: 'path/to/config.json' });
nconf.set('database:host', '127.0.0.1');
nconf.set('database:port', 5984);
console.log('foo: ' + nconf.get('foo'));
console.log('NODE_ENV: ' + nconf.get('NODE_ENV'));
console.log('database: ' + nconf.get('database'));Start it with an environment variable and a flag, exactly as the README does:
NODE_ENV=production node sample.js --foo barThe README states the output is foo: bar, NODE_ENV: production, and database: { host: '127.0.0.1', port: 5984 }. The flag wins for foo because argv was attached first; the environment variable is visible because env() was attached second. The database object comes from the values set in the script, not from the file. If you swap the attach order, the printed values change, and that is the whole mental model.
Writing configuration back is a separate call. nconf.save() persists the store, and the README pairs it with a read of the resulting JSON file to show what landed on disk.
Required keys, chained stores and where nconf stops helping
nconf.required(keys) declares string keys as mandatory and throws if any are missing. The README shows the error text: Missing required keys: keyb. The more interesting form is chaining required() between file attachments, so that a later file path can depend on a value loaded earlier. The README example reads STAGE, requires it, resolves configs/stages/<STAGE>.json, then requires OAUTH:redirectURL before loading the OAuth file, and finally pulls in a logs store whose path depends on LOGS_MODE.
That chain is the strongest argument for nconf over a hand-rolled loader, and also the clearest boundary. required() checks presence, not type, range or format. A port read as the string "5984" from an environment variable is a string, and nothing in the provider converts it. There is no schema, no coercion layer and no validation hook in the API documented in the README.
The second boundary is format. The package depends on ini, so JSON and INI are covered by the built-in file store. YAML is not in the dependency list; it appears in devDependencies as nconf-yaml, a separate package the test suite uses. If your configuration files are YAML, you are adding a third-party store, and the README does not document what that store supports.
The third boundary is runtime change. Nothing in the documented API watches a file for edits. Configuration is read when you attach a store and when you call get(). A long-running process that expects a config file change to take effect without a restart will not get that behaviour from nconf.
nconf against dotenv and a schema validator
The nearest alternative for many teams is dotenv, and the difference is structural rather than cosmetic. dotenv reads a .env file and copies its contents into process.env. Precedence is then whatever the process environment already had, and every consumer reads process.env directly, so there is no ordering you can rearrange in code and no way to attach a second file with a lower priority. nconf keeps sources as ordered stores behind one provider, so argv, env, a file and defaults can be layered and the layering is visible.
The other comparison is a schema validator such as a JSON Schema or object-schema library layered on top of process.env. Those give you type coercion, defaults and a startup failure with a field-level message, which nconf does not. What they do not give you is nconf's store ordering or the chained required() pattern where one file's path depends on a value from an earlier source. The honest split: use nconf when precedence and store composition are the hard part, and put a validator on top of nconf's output when types are the hard part. Do not expect nconf to be both.
Maintenance, the 1.0.0 beta and what MIT means here
The repository is not archived, and the last push was on 2026-07-25, so there is recent activity on master. The release history is less even. v0.12.1 shipped on 2023-10-23, then v0.13.0 and v1.0.0-beta.2 both shipped on 2025-04-14, and the version in package.json is 1.0.0-beta.2. A stable 1.0.0 has not been released, which means the current published line is a beta that has been in that state since April 2025. The API documented in the README is the API you get, and it has been stable in shape for years, but the version number is a real signal about what the maintainers consider finished.
Upgrade cost is low by inspection. Two runtime dependencies, ini ^2.0.0 and yargs ^17.0.0, and a test script that runs jest --verbose. A major yargs bump is the kind of change that would surface in argv parsing, and the README passes options straight through to yargs, so flags handled by yargs are the area to check when upgrading. Renovate and release-it are configured in the repository, which suggests dependency updates and releases are partly automated.
The licence is MIT, declared in package.json and present as a LICENSE file at the repository root. MIT permits use in proprietary software with the copyright notice retained. That is the extent of what the repository states; it is not legal advice, and anything beyond redistribution and modification terms belongs with your own counsel.
Editorial conclusion
Adopt nconf if you want a small, MIT licensed store where the precedence of argv, env and files is explicit in code and readable in one screen. Do not adopt it if you need validation schemas, typed parsing or hot reload; nconf gives you required() and nothing else. Before committing, run the sample from the README with NODE_ENV=production node sample.js --foo bar and confirm the printed values match the order you attached, then check whether you need a format beyond JSON and INI, because YAML lives in the separate nconf-yaml package.
Frequently asked questions
What is nconf in Node.js?
nconf is a hierarchical configuration store for Node.js that reads values from command-line arguments, environment variables, files and in-code defaults. The order in which you attach those sources determines which one wins for a given key.
How do I install nconf from npm?
Install it as a project dependency with npm install nconf. The package is published as nconf and its runtime dependencies are ini and yargs.
What precedence does nconf use for argv, env and files?
The README states that the order in which you attach configuration sources determines their priority in the hierarchy. In its sample, argv() is attached before env() and the file store, so a command-line flag wins over an environment variable of the same name.
Does nconf validate configuration values?
Only for presence. nconf.required(keys) throws an error listing missing keys, but the documented API has no type coercion or schema validation, so a port read from an environment variable stays a string.
Does nconf support YAML configuration files?
Not in the core package. The runtime dependencies are ini and yargs; YAML support appears as the separate nconf-yaml package in devDependencies.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/indexzero-nconf)