Coming from rc
An rc alternative with a drop-in path: import rc from seniority/rc, graded 1 / 1 by rc's own test — one exit-code bit, not a case count — then rc's file stack and merge with none of its four dependencies, and a resolver that says where every value came from.
seniority is an rc alternative that also covers what cosmiconfig, dotenv and
find-up do beside it: one resolution for flags, environment, config files, a
package.json field and defaults, in a fixed order, with no dependencies.
Migrate from rc in one import
- import rc from 'rc';
+ import rc from 'seniority/rc';The call is rc's — rc(name, defaults, argv, parse) — and so is what it does: the file stack
in rc's own order (/etc/<name>/config, /etc/<name>rc, the four places under the home
directory, the nearest .<name>rc walking up from the working directory, then a file named
by config in the environment or on the command line), <name>_* environment keys with __
read as nesting, JSON with comments, deep-extend's merge (arrays replaced, not
concatenated), a string defaults read as JSON, and the configs / config report of which
files were read. Like rc, it reads the process's environment when you pass none.
Two differences, both on purpose.
- INI is refused by name, not parsed. seniority bundles no format parser, so a file that
is not JSON is refused with the fix in the error. Pass
ini.parsein rc's own fourth position and you have rc's behaviour, with the parser as your dependency rather than everyone's. - The command line is an argument. When
argvis falsy, rc 1.2.8 fills it withminimist(process.argv.slice(2));seniority/rctreats an omittedargvas empty and never reads the command line. Pass the flags you already parsed as the third argument.
import rc from 'seniority/rc';
const config = rc('mytool', defaults, flags);A fifth argument, { env, cwd, home, win }, supplies the rest of the world when you would
rather not have it read from the process — which is how it is tested.
Is seniority compatible with rc?
Graded, and the grade is coarse. rc's test/test.js, vendored from 1.2.8 and unmodified
apart from the import specifier, runs against seniority/rc beside a control that runs it
against real rc:
| passing | grade | |
|---|---|---|
seniority/rc | 1 / 1 | by exit code |
| rc itself (control) | 1 / 1 | by exit code |
From Compatibility, which npm run compat:page generates from the
oracle's last run; that page is the authority. Read 1 / 1 as one bit, not one case: rc's
suite is scripts of bare assert calls with no reporter, so the only honest grade is that
the script ran against this target and exited 0. That script covers an environment option,
a nopt-shaped argv outranking it, and a commented JSON .<name>rc in the working directory
with its config and configs report. rc 1.2.8 was never tagged upstream, so the suite is
taken from the repository's head at commit a97f6ad. rc's two other test files are not
graded: ini.js tests an internal and the ini package, and nested-env-vars.js is public
and not graded yet.
The same page grades seniority (cosmiconfig's own suite), seniority/lilconfig and
seniority/dotenv.
What you gain over rc
rc 1.2.8 depends on deep-extend, ini, minimist and strip-json-comments.
seniority/rc depends on nothing. And where rc merges, seniority also resolves the value
and keeps the receipt:
- Provenance on every value.
resolve()returns each option's winning source and every candidate it beat, where rc'sconfigsonly lists the files it read.explanationJson()is that record as--jsondata andexplanationEvent()as an agent event, generated by the code that picked the value. - An order nobody can rearrange.
flag > env > config file > package.json field > default, exported asORDER. A plugin can add a source between them and can never beat the flag the user typed. - A bounded walk. The upward search for
.<name>rcstops at sixty-four levels, so no directory tree can turn it into a hang.
When to switch from rc
- Your rc files are JSON, or you are content to pass
ini.parsein. - You already parse your own flags, and would rather rc did not parse
process.argva second time behind them. - "Why is this set to that?" is a question your users or agents ask.
The API, the discovery rules and the other drop-in paths are on seniority.