argsbarg
v1.2.0
Published
 <!-- Big money NE - https://patorjk.com/software/taag/#p=testall&f=Bulbhead&t=shebangsy&x=none&v=4&h=4&w=80&we=false> -->
Readme

Build beautiful, well-behaved CLI apps with Bun — no third-party runtime dependencies.
Why another CLI parser?
Schema-first -- define your entire CLI’s structure, commands, options, and help in a single, explicit data model, making the command-line interface centralized, clear, and self-describing upfront.
Bun-optimized -- built from the ground up for Bun and TypeScript, leveraging Bun’s performance and modern JavaScript features without any extra dependencies.
Also checkout ArgsBarg for cpp, nim, and swift!
Halps! -->

Sub-level Halps! -->

Shell completions! -->

Usage
import { cliRun, CliCommand, CliOptionKind } from "argsbarg";
const cli: CliCommand = {
key: "helloapp",
description: "Tiny demo.",
positionals: [
{
name: "name",
description: "Who to greet.",
kind: CliOptionKind.String,
argMin: 0,
argMax: 1,
},
],
options: [
{
name: "verbose",
description: "Enable extra logging.",
kind: CliOptionKind.Presence,
shortName: "v",
},
],
handler: async (ctx) => {
const name = ctx.args[0] ?? "world";
if (ctx.hasFlag("verbose")) {
console.log("verbose mode");
}
console.log(`hello ${name}`);
},
};
await cliRun(cli);cliRun parses process.argv, prints help or errors, dispatches the leaf handler, and exits the process.
What is it?
Everything you need for a first-class CLI:
- Nested subcommands (
CliCommandwithcommandsfor groups,handlerfor leaves) - POSIX-style options (
-x,--long,--long=value) - Bundled presence flags (
-abc) - Positional arguments and varargs tails (
CliPositionalobjects onpositionals) - Scoped help at any routing depth (
-h/--help) - Default-command fallback (
CliFallbackMode) - Option separator (
--to stop option parsing) - Rich help: rounded UTF-8 boxes, tables, terminal width detection (
process.stdout.columns), colors when stdout/stderr is a TTY - TypeScript-native: Typed option accessors (
ctx.typedOpt<T>) andasync/awaithandler support.
Built-ins
Every app gets:
-h/--helpat any routing depth (scoped help).completion bash/completion zsh— print shell completion scripts to stdout (injected bycliRun).
Do not declare a top-level command named completion — it is reserved for this built-in.
Shell completions
myapp completion bash > ~/.bash_completion.d/myapp
# or: source <(myapp completion bash)
myapp completion zsh > ~/.zsh/completions/_myapp
# then: fpath+=(~/.zsh/completions); autoload -Uz compinit && compinit
# or, for a one-off test in the current shell: eval "$(myapp completion zsh)"Install
bun add bun-argsbargHow it works
- Build a program root
CliCommandusing pure TypeScript objects:keyis the app/binary name,commandsare top-level subcommands,optionsare global flags. The root must not sethandleror declarepositionals(validated at startup). UsefallbackCommand/fallbackModeon the root only for default top-level routing. - Call
await cliRun(root)with that root — validates, parses argv, renders help or errors, invokes the leaf handler, andprocess.exits with status 0 on success, 1 on implicit help or error (explicit--help→ 0). - From a handler,
cliErrWithHelp(ctx, "message")prints a red error line plus contextual help on stderr and exits 1.
Fallback modes (CliFallbackMode)
| Mode | Empty argv | Unknown first token |
| --- | --- | --- |
| MissingOnly | Default command | Error |
| MissingOrUnknown | Default command | Default command (token becomes argv for the default) |
| UnknownOnly | Root help (exit 1) | Default command |
With MissingOrUnknown / UnknownOnly, unrecognized root flags stop root-flag consumption and the remainder is passed to the default command.
Positionals (help labels)
Add CliPositional entries to the command’s positionals list (separate from CliOption flags). With argMax: 0, the tail accepts at least argMin tokens and has no upper bound unless you set argMax > 0.
| Fields | Label |
| --- | --- |
| omit argMin / argMax (defaults 1 / 1, one required word) | <n> |
| argMin: 0, argMax: 1 | [n] |
| argMin: 0, argMax: 0 | [n...] |
| argMin: 1, argMax: 0 | <n...> |
Reading values (CliContext)
ctx.flag("verbose")— presence options (boolean).ctx.stringOpt("name")/ctx.numberOpt("count")—string | undefined/number | null.ctx.typedOpt<T>("custom", parseFn)— pass a custom parsing function for type-safe option resolution.ctx.args— positional words in order asstring[].ctx.schema— merged program root (CliCommand) for contextual help.
Examples
Check the examples/ directory for full working scripts:
| Example | File | Shows |
| --- | --- | --- |
| ArgsBargMinimal | examples/minimal.ts | String + presence flags, MissingOrUnknown fallback. |
| ArgsBargNested | examples/nested.ts | Nested CliCommand tree, positional tails, async handlers. |
export PATH="$PATH:$(pwd)/examples"
eval "$(minimal.ts completion zsh)"
minimal.ts --help
minimal.ts hello --name world
eval "$(nested.ts completion zsh)"
nested.ts stat owner lookup -u alice ./README.md
nested.ts read ./README.mdPublic API overview
The package root (argsbarg / src/index.ts) exports the types and runtime you need to define a schema and run it. Parsing, completion script generation, help rendering, and schema pre-validation live in other modules under src/ for tests and advanced integrations.
| Symbol | Role |
| --- | --- |
| CliCommand, CliOption, CliPositional, CliHandler | Schema and handler types. |
| CliOptionKind, CliFallbackMode | Option kinds and root fallback behavior. |
| CliSchemaValidationError | Thrown when the static command tree violates schema rules. |
| CliContext | Handler context (ctx.flag, ctx.stringOpt, ctx.args, …). |
| cliRun(root, [argv]) | Validate, parse argv, dispatch, exit. |
| cliErrWithHelp(ctx, msg) | Print error + scoped help on stderr, exit 1. |
Reserved identifier (validated at startup): root command completion.
License
MIT
