minargs
is an argument parser with minimal configuration & assumptions. Argument parsing can take many shapes but the explicit goals of this library are as follows:
- no usage
- no validation
- no types or type cohersion
- no regular expressions
- no strictness
- no dependencies
- no vulnerabilities
- minimal assumptions
- minimal configuration
- 100% test coverage
- Bring Your Own Usage™️
- Bring Your Own Validation™️
npm install minargs
argv
(Array
)- Default:
process.argv
- The argument strings to parse
- Default:
known
(Array
)- Default: none
- ...
aliases
(Object
)- Default: none
- ...
multiples
(Array
)- Default: none
- ...
positionalValues
(Array
)- Default: none
- ...
{
args: {},
values: {},
positionals: [],
remainder: [],
process: []
}
- Returned values are a string by default
- Returned values are an array of strings if the corresponding arg was defined in
multiples
- Examples:
--foo=bar
will returnundefined
with no configuration--foo=bar
will return"bar"
when'foo'
--foo bar
will return"bar"
when'foo'
&positionalValues
istrue
- Notably,
bar
is treated as a positional & returned inpositionals
ifpositionalValues
isfalse
- Notably,
- Returned value is the remaining array of results from
process.argv
after the first bare--
- Notably, this is useful for recursively parsing arguments or passing along args to other processes
- Returned value is an array associated with
process
args split fromprocess.argv
at the beginning of parsing if the defaultprocess.argv
is being parsed- Notably,
mainArgs()
is used to determine these values
- Notably,
- Returned value will be an empty array if an explicit array to parse was passed to
minargs()
$ basic.js - --foo=bar -- --baz
#!/usr/bin/env node
// basic.js
const { minargs } = require('minargs')
const { args, values, positionals, remainder, process } = minargs()
args // { "foo": true }
values // { "foo": "bar" }
positionals // ["-"]
remainder // ["--baz"]
process // [ "/path/to/node", "/path/to/program/cli.js" ]
$ exists.js --foo
#!/usr/bin/env node
// exists.js
const { minargs } = require('minargs')
const { args } = minargs()
if (args.foo) {
// ...
}
$ unknown.js --baz
#!/usr/bin/env node
// unknown.js
const { minargs } = require('minargs')
const { args } = minargs()
const known = ['foo', 'bar']
const unknown = Object.keys(args).filter(arg => !known.includes(arg))
if (unknown.length > 0) {
console.error('unknown flags passed:', unknown)
// stop the process & set an `exitCode` appropriately
process.exit(1)
}
// ...
$ validate.js --num=1337
#!/usr/bin/env node
// validate.js
const { minargs } = require('minargs')
const { args, values } = minargs()
const usage = {
num: {
validate: (value) => {
if (!isNaN(value)) {
return Number(value)
}
throw Error('Validation error!')
}
},
force: {
validate: (value) => {
if (~['true','false'].indexOf(value.toLowerCase())) {
return Boolean(value)
}
throw Error('Validation error!')
}
}
}
Object.keys(args).filter(name => args[name]).map(name => {
usage[name].validate(values[name])
})
// ...
$ recursive-parse.js
#!/usr/bin/env node
// recursive-parse.js
const { minargs } = require('minargs')
function minargsRecursiveSyncArray(argv, arr) {
arr = arr || []
const result = minargs(argv)
arr.push(result)
if (result.remainder.length > 0) {
minargsRecursiveSyncArray(result.remainder, arr)
}
return arr
}
minargsRecursiveSyncArray(process.argv) // array of results
function minargsRecursiveSyncFlat(argv, obj) {
const result = minargs(argv)
obj = obj || { args: {}, values: {}, positionals: [] }
obj.args = { ...obj.args, ...result.args }
obj.values = { ...obj.values, ...result.values }
obj.positionals = obj.positionals.concat(result.positionals)
if (result.remainder.length > 0) {
minargsRecursiveSyncFlat(result.remainder, obj)
}
return obj
}
minargsRecursiveSyncFlat(process.argv) // flattened results object
// ...
$ mkdir.js ./path/to/new/dir/ --force --verbose --parents
#!/usr/bin/env node
// mkdir.js
const knownOpts = ['force']
const { flags, positionals } = parseArgs({ withValue: knownOpts })
const args = Object.keys(flags).filter(f => knownOpts[f])
const cmd = (flags.force) ? 'sudo mkdir' : 'mkdir'
process('child_process').spawnSync(cmd, [...args, ...positionals])
$ usage.js -h
#!/usr/bin/env node
// usage.js
const { minargs } = require('minargs')
const usage = {
help: {
short: 'h',
usage: 'cli --help',
description: 'Print usage information'
}
force: {
short: 'f',
usage: 'cli --force',
description: 'Run this cli tool with no restrictions'
}
}
const opts = {
known: Object.keys(usage),
multiple: Object.keys(usage).filter(arg => usage[arg].multiple),
alias: Object.keys(usage).filter(arg => usage[arg].short).reduce((o, k) => {
o[usage[k].short] = k
return o
}, {})
}
const { args } = minargs(opts)
if (args.help) {
Object.keys(usage).map(name => {
let short = usage[name].short ? `-${usage[name].short}, ` : ''
let row = [` ${short}--${name}`, usage[name].usage, usage[name].description]
console.log.apply(this, fill(columns, row))
})
}
/// ...
- Strictness is a function of usage. By default,
minargs
does not assume that anyknown
or "unknown" arguments should or shouldn't be allowed. Usage examples above show how you can quickly & easily utilizeminargs
as the backbone for an application which does enforce strictness though.
- Yes.
-a
&-aCdeFg
are supported-a=b
will capture & return"b"
as a value-a b
will capture & return"b"
as a value ifpositionalValues
istrue
- An alias can be any other string that maps to the canonical option; this includes single characters which will map shorts to a long-form (ex.
alias: { f: foo }
will parse-f
as{ args: { 'foo': true } }
)
- Yes.
- No.
- No.
- No.
- It would set
{ args: { 'no-foo': true } }
- No.
- No.
- Yes.
- Any arguments following a bare
--
definition will be returned inremainder
.
- No.
- The only way to determine if
--
was present & there were arguments passed afterward is to check the value ofremainder
- Yes.
- A bare
-
is treated as & returned inpositionals
- No.
-bar
will be parsed as short options, expanding to-b
,-a
,-r
(ref. Utility Syntax Guidelines in POSIX.1-2017)
- No.
---foo
returns{ args: '-foo': true }
--foo
returns{ args: { 'foo': true }
- Yes.
- No.
--number -2
will be parsed as{ args: { 'number': true, '2': true } }
- You will have to use explicit value setting to make this association (ex.
--number=-2
)
minargs
has a companion CLI library: @minargs/cli
# install package globally & call bin...
npm install minargs -g && minargs
# or, use `npx` to install & call bin...
npx minargs
minargs "<args>" [<options>]
To learn more, check out the @minargs/cli
GitHub repository or package page