argvex
v0.0.5
Published
Lightweight and unopinionated CLI argument parser — just a parsing tool, not a framework
Maintainers
Readme
Table of Contents
Overview
Why argvex?
You want to roll-your-own CLI, but argument parsing is such a headache?
Let argvex handle the annoying part, and nothing else.
argvex is a minimalist argument parser that stays out of your way with little to no API,
so you can keep full control, define your own rules, and avoid framework baggage.
Key Features
Getting started
argvex gives you a structured view of your command-line input — flags, values,
and operands — without forcing schemas, coercion, or assumptions.
How to install
npm install argvexHow to use
You can just call argvex() to get structured process.argv output.
brewer brew espresso --size medium --shots 3 --milk none --temperature 92 --crema thickimport argvex from 'argvex'
const args = argvex()
// args -> { _: [ "brewer", "brew", "espresso" ], "size": [ "medium" ], shots: [ "3" ], milk: [ "none" ], temperature: [ "92" ], crema: [ "thick" ] }A GNU-flavoured value assign using "=" works too!
brewer brew cappuccino --size=large --shots=2 --milk=steamed --foam=thickimport argvex from 'argvex'
const args = argvex()
// args -> { _: [ "brewer", "brew", "cappuccino" ], "size": [ "large" ], shots: [ "2" ], milk: [ "steamed" ], foam: [ "thick" ] }When it comes to boolean flags, just check for their presence.
import argvex from 'argvex'
const args = argvex()
if (!!args.decaf) {
console.log("Making a decaf coffee!")
}You can use standalone short flags or use them in groups.
brewer brew americano -qs -m water -t 85import argvex from 'argvex'
const args = argvex()
// args -> { _: [ "brewer", "brew", "americano" ], "q": [], "s": [], m: [ "water" ], t: [ "85" ] }Use -- (end-of-options delimiter) to separate flags from operands that might look like flags.
brewer brew --milk oat -- --not-a-flag latteimport argvex from 'argvex'
const args = argvex()
// args -> { _: [ "brewer", "brew", "--not-a-flag", "latte" ], milk: [ "oat" ] }Aliases
While you can code your own support for aliases easily,
argvex can handle those out-of-the-box if you pass a minimal schema to it.
brewer brew mocha -d -m oat -c darkimport argvex from 'argvex'
const schema = [
{ name: "decaf", alias: "d" },
{ name: "milk", alias: "m" },
{ name: "chocolate", alias: "c" }
]
const args = argvex({ schema })
// args -> { _: [ "brewer", "brew", "mocha" ], "decaf": [], milk: [ "oat" ], chocolate: [ "dark" ] }POSIX-flavoured
While argvex aims at being a minimalist tool, it can support most of the POSIX-flavoured syntax if you pass a schema to it.
brewer brew -dsmedium -h2 macchiatoimport argvex from 'argvex'
const schema = [
{ name: "decaf", alias: "d", arity: 0 },
{ name: "size", alias: "s", arity: 1 },
{ name: "shots", alias: "h", arity: 1 },
]
const args = argvex({ schema })
// args -> { _: [ "brewer", "brew", "macchiato" ], "decaf": [], size: [ "medium" ], shots: [ "2" ] }Repeating flags
By default, repeating a flag will override its previous value. If you want values to accumulate instead, enable additive mode.
brewer brew flat-white --milk steamed --milk foamed --milk microfoamimport argvex from 'argvex'
const schema = [
{ name: "milk", arity: 3 },
]
const args = argvex({ schema, additive: true })
// args -> { _: [ "brewer", "brew", "flat-white" ], milk: [ "steamed", "foamed", "microfoam" ] }Strict Mode
You may force argvex to throw an error whenever unexpected flag or value gets passed.
brewer brew cortado --size small --shots 1 --no-payimport argvex from 'argvex'
const schema = [
{ name: "size", arity: 1 },
{ name: "shots", arity: 1 },
]
const args = argvex({ schema, strict: true })
// args -> ArgvexErrorExamples of common patters
argvex doesn't try to do anything more than parsing itself, so it's up to you how you want to handle the rest.
Here are some common patterns you might find useful.
Case with required flags
Sometimes you need to ensure certain flags are provided. You can check for their presence and throw an error if they're missing.
import argvex from 'argvex'
const args = argvex()
if (!args.temperature) {
throw new Error('You must provide "--temperature" flag first.')
}Case with default values
When optional flags aren't provided, you can set sensible defaults.
import argvex from 'argvex'
const args = argvex()
if (!args.milk) {
args.milk = [ "steamed" ]
}Case with value coercion
Since argvex returns all values as strings, you'll often want to convert them to the appropriate types.
import argvex from 'argvex'
const args = argvex()
if (args.temperature) {
args.temperature = args.temperature.map(temperature => parseInt(temperature, 10))
}Case with error handling
Wrap argvex calls in try-catch to handle parsing errors gracefully.
import argvex, { ArgvexError } from 'argvex'
try {
const args = argvex({ strict: true })
// todo: process args here
} catch (error) {
if (error instanceof ArgvexError) {
console.error('Invalid command line arguments')
process.exit(1)
}
throw error
}