A lightweight CLI flag/argument parser for Node.js.
Supports all standard CLI flag formats and named positional arguments.
- Supports ESM, CommonJS, TypeScript
- Short
-f
and long--flag
flags - Grouped short boolean flags
-xyz
- Values via
--key=value
or--key value
- Multi-value flags via
array
option - Negated flags
--no-color
- Boolean-only flags via
boolean
option - Named and variadic (
...rest
) positional arguments viaargs
option - Short-to-long mapping via
alias
option - Auto-casts numbers and booleans from values
- Default values via
default
option - Dashed keys also available as camelCase
- Captures arguments before and after
--
terminator
npm i flaget
Example command-line with flags and positional arguments:
$ cli.js report daily -xz --foo-bar baz --keys foo bar --start=5 -l 20 -- one --two
const flaget = require('flaget');
// or, in ESM:
// import flaget from 'flaget';
const cliParams = flaget();
console.log(cliParams);
const cliParams = flaget({
// raw: process.argv.slice(2), // raw argument values (parses by default)
args: ['command', 'period'], // named positional arguments
alias: { l: 'limit' }, // -l = --limit
array: ['keys'], // collect multiple values for --keys
default: { limit: 10, verbose: false } // default values if not set in CLI
});
console.log(cliParams);
Result:
{
args: { command: 'report', period: 'daily', }, // named positional arguments
flags: {
x: true,
z: true,
'foo-bar': 'baz',
fooBar: 'baz',
keys: ['foo', 'bar'], // collected multiple values
start: 5,
limit: 20, // long alias to short 'l'
verbose: false,
},
_: ['report', 'daily'], // positional arguments before "--"
_tail: ['one', '--two'] // everything after "--"
}
Flags can behave as booleans, accept a single value, or collect multiple values.
Their behavior depends on syntax, position, and parser options like boolean
and array
.
Input | Output | Condition |
---|---|---|
--flag or -f |
{ flag: true } |
Next token is absent or starts with - |
--flag=value |
{ flag: 'value' } |
Always treated as key=value |
--flag value |
{ flag: 'value' } |
Next token is a value and flag is not in boolean option |
--flag arg |
{ flag: true }, _: ['arg'] |
flag is in boolean option |
-xyz |
{ x: true, y: true, z: true } |
Grouped short flags, always true |
--no-flag |
{ flag: false } |
Negated flag, always false |
--flag val1 val2 |
{ flag: ['val1', 'val2'] } |
flag is in array option |
The function accepts an optional configuration object to customize the parsing behavior. These options control how flags, positional arguments, aliases, arrays, and defaults are handled.
Option | Type | Default | Description |
---|---|---|---|
raw |
string[] | process.argv.slice(2) |
The input raw CLI argument array to parse. Defaults passed as process.argv.slice(2) . |
args |
string[] | [] |
List of named positional arguments. Values are assigned in order. Supports a variadic last argument with the ...name syntax to collect all remaining positional arguments into a single key, before terminator -- . |
alias |
Object | {} |
Mapping of short flag keys to long keys. For example, { f: 'files' } will map -f to --files . |
array |
string[] | [] |
List of flag keys that should collect multiple values into arrays. Values are collected until the next flag, terminator -- or the end of input. |
boolean |
string[] | [] |
List of flag keys that should always be parsed as booleans. These flags never consume a value, even if the next argument looks like one. |
default |
Object | {} |
Map of default values for flags that are not provided on the CLI. |
The function returns an object containing the parsed command-line arguments, separated into flags,
positional arguments, and any arguments following a --
terminator.
Named positional arguments are mapped into the args
object.
Property | Type | Description |
---|---|---|
args |
Object | Object with named positional arguments based on args option. |
flags |
Object | Object containing all parsed flags, including aliases and camelCase keys. |
_ |
string[] | Positional arguments before the -- terminator. |
_tail |
string[] | Arguments after the -- terminator (unparsed, passed as-is). |
Named positional arguments with variadic ...files
.
$ convert.js mp3 --bitrate 128 file1.wav file2.wav
const cliParams = flaget({
args: ['format', '...files'],
});
console.log(cliParams);
Output:
{
args: { format: 'mp3', files: ['file1.wav', 'file2.wav'] },
flags: { bitrate: 128 },
_: ['mp3', 'file1.wav', 'file2.wav'],
_tail: []
}
Short to long flag mapping.
$ cli.js -f log.txt
const cliParams = flaget({
alias: { f: 'file' }
});
console.log(cliParams);
Output:
{
args: {},
flags: { file: 'log.txt' },
_: [],
_tail: []
}
Collect multiple values.
$ cli.js --keys x y z
const cliParams = flaget({
array: ['keys']
});
console.log(cliParams);
Output:
{
args: {},
flags: { keys: ['x', 'y', 'z'] },
_: [],
_tail: []
}
Prevent consuming next value.
$ cli.js --debug input.txt
const cliParams = flaget({
boolean: ['debug']
});
console.log(cliParams);
Output:
{
args: {},
flags: { debug: true },
_: ['input.txt'],
_tail: []
}
Set fallback values for missing flags.
$ cli.js
const cliParams = flaget({
default: { verbose: false, port: 8080 }
});
console.log(cliParams);
Output:
{
args: {},
flags: { verbose: false, port: 8080 },
_: [],
_tail: []
}
$ cli.js push --verbose origin main -- --dry-run --no-cache
const cliParams = flaget({
args: ['command', '...targets'],
boolean: ['verbose'],
});
console.log(cliParams);
Output:
{
args: {
command: 'push',
targets: ['origin', 'main'],
},
flags: {
verbose: true
},
_: ['push', 'origin', 'main'],
_tail: ['--dry-run', '--no-cache']
}