Reference
@hulla/args reference
Look up argument constructors, parsed result fields, parser settings, and error metadata.
On this page
Find argument constructors, parsed result fields, and parser defaults below. For a working command before the details, follow Build a greeting command.
| Constructor | Config fields | Default and result |
|---|---|---|
flag(config) | name: string, optional description: string, schema?: ZodTypeAny, long?: string | string[], short?: string | string[] | Defaults to z.boolean() and derives long/short forms from name. Absent: value: false, detected: false. |
option(config) | Same named fields as flag | Defaults to z.string(). Absent: value: undefined, detected: false. |
positional(config) | name: string, optional description: string, schema?: ZodTypeAny | Defaults to z.string(); consumes one unclaimed token not beginning with -. |
sequence(config) | name: string, optional description: string, required arguments: Positional[] | No caller schema; .value maps member names to their result records. The sequence is detected only when every member matches. |
infiniteSequence(config) | name: string, optional description: string, optional schema: ZodArray<ZodString> | Defaults to z.array(z.string()); collects remaining unclaimed non-option tokens. With none, .value is [] and detected is false. |
command(config) | name: string, optional description: string, alias?: string | string[], arguments?: Argument[], commands?: Command[] | Declares a branch under result.commands[name]. The typed result has detected, arguments, and nested commands; aliases still use the canonical name as the result key. |
All argument constructors accept a Zod schema except sequence, which uses its members’ schemas. infiniteSequence accepts an array-of-strings schema. See Validation for missing-input behavior.
The package also exports these types:
import type {
ArgType,
PossibleArguments,
ArgumentConfig,
CommandConfig,
Flag,
Option,
Positional,
Sequence,
InfiniteSequence,
Command,
Parser,
ArgOutput,
ParserResult,
ParserSettingsInit,
ParserSettings,
Code,
ParserErrorConstructor,
} from '@hulla/args'ParserResult contains argv, arguments, and commands. A nested command result contains detected, arguments, and its own commands.
Named forms and matching
For flags and options, name: 'output' accepts --output and -o. Customize the spellings with:
| Config | Accepted names |
|---|---|
short: 'f' | --output, -f |
long: ['out', 'dest'] | --output, --out, --dest, -o |
Dashes are optional in these declarations. Duplicate names or aliases fail when you create the parser.
mode: 'both' accepts long and short spellings; 'long' and 'short' limit them. sharedDash: true permits flag groups such as -qv; every configured short name must then be one character. For options, a grouped option consumes a following value, for example -vo file when v is a flag and o an option.
Each ordinary argument result has this shape:
{
value: unknown, // TypeScript infers the Zod output type
raw: string | undefined,
index: number, // index in the read slice (plus nested offset); -1 when absent
detected: boolean,
parser: string // parser path, e.g. "notes.add"
}raw keeps exactly what was matched. For --output report.txt, it is '--output report.txt'; for --output=report.txt, it is '--output=report.txt'.
index points to the first matched token in the slice the parser reads. If you skip two entries with startIndex: 2, index 0 refers to the third entry of the original array. Nested commands add their offset within the same slice.
The top-level argv contains that parsed slice. It is lowercased when caseSensitive is false; use raw when you need the original text.
Omitted options and positionals have value: undefined, raw: undefined, index: -1, and detected: false. Their schemas don’t run, so a Zod .default() won’t supply a fallback.
A present option without a following value is different: it remains detected and can use the option token itself as its candidate value. Empty equals-form values skip schema validation. Use requireEquals to reject a present option without =, and check both detected and value when input is required.
Other constructors have their own empty-input behavior:
- Flags validate
falsewhen absent andtruewhen present. infiniteSequencevalidates an empty array when no tokens were collected.sequencereturns a record per member, plus its combinedraw, firstindex, anddetectedfields.
parser({ name, arguments?, commands?, settings? }) returns the parser’s name, normalized settings, and two methods: read(argv) and parse(argv).
read() selects the input from startIndex (inclusive) to stopIndex (exclusive). The defaults read the whole array. Either pass process.argv.slice(2) with those defaults, or pass the full process.argv with startIndex: 2.
| Setting | Default | Effect |
|---|---|---|
caseSensitive | false | Match command and argument names without case sensitivity. Equals-form values are taken from the normalized token, so they are lowercased too; space-separated and positional values retain original casing. |
mode | 'both' | Accept long and short option/flag forms; can be 'long' or 'short'. |
requireEquals | false | Require an option value in --name=value form. |
keepOnlyDetected | false | Remove undetected entries from the returned results; parsing and validation rules stay the same. |
mergeArgs | false | Let root and selected command parsers inspect shared arguments across the command boundary. Without it, each parser sees its own command slice. |
sharedDash | false | Expand grouped single-character short forms. |
startIndex | 0 | First argv entry to read. |
stopIndex | null | Exclusive end of the argv slice. |
See Parser options for argv ownership and examples; see Commands for scope and merging.
ParserError extends Error and exposes message, parser, from, code, argvIndex, argumentName, and path.
Source (from) | Diagnostic behavior |
|---|---|
zod | First issue, argvIndex: -1, empty argumentName. |
parser | Can identify an argv token; declaration errors can use -1. |
runtime | Runtime failure details. |
Treat path as diagnostic metadata. It isn’t a guaranteed argument-name lookup, and every error doesn’t have a user-supplied token index.
Parser construction can throw for duplicate/ambiguous declarations (including invalid sharedDash short-name lengths); parsing can throw on invalid schema input or unmatched/unhandled tokens. Required input is an application decision: check detected and report your own missing-value message. @hulla/args does not render help or set process exit codes. See Validation for a CLI-boundary catch example.