Type-Safe CLI Argument Parser
cli-vir is a command-line interface (CLI) argument parser for Node.js, built with a strong emphasis on type safety for parsed arguments. The current stable version is 1.0.3, indicating active development with frequent patch releases addressing minor issues and dependency updates. Key differentiators include its flexible handling of flag formats (single/double dashes, short/long forms), support for case-insensitive flag names across camelCase, kebab-case, and snake_case variants, and robust options to restrict argument values to specific sets or convert truthy/falsy strings to booleans. It provides comprehensive type inference for parsed values and automatically generates man-page-style documentation for parsing failures. This library streamlines CLI development by abstracting away common parsing complexities and enhancing developer experience with strong type guarantees. It requires Node.js version 22 or higher.
Common errors
-
TypeError: parseArgs is not a function
cause Attempting to use `require()` syntax for `cli-vir`, which is an ESM-first module.fixChange your import statement to use ESM syntax: `import { parseArgs } from 'cli-vir';` and ensure your project is configured for ESM (e.g., `"type": "module"` in `package.json`). -
TS2345: Argument of type 'string' is not assignable to parameter of type 'boolean'.
cause A flag argument was defined without a `valueRequirement` or with `FlagRequirement.Blocked`, implying a boolean flag, but a string value was provided on the command line.fixAdjust your `FlagRequirement` in the argument definition (e.g., `FlagRequirement.Required` for a string value) or ensure the CLI input matches the expected type (e.g., pass the flag without a value for a boolean flag). -
ReferenceError: import_meta is not defined
cause The `import.meta` object is used in the `parseArgs` options but the file is being executed in a CommonJS context or an environment where `import.meta` is not available.fixEnsure your project is configured for ESM (e.g., `"type": "module"` in `package.json`) and you are running Node.js version 12.0.0 or higher, where `import.meta` was introduced for ESM modules.
Warnings
- breaking The `ParsedArg` type was renamed to `ParsedArgs`. If you were explicitly typing your parsed arguments, you must update the type name.
- breaking Version 1.0.0 introduced a major bump, which may include breaking changes in internal structures or API behavior not explicitly detailed in release notes beyond 'bump to v1'. It also added support for an array of binary names. Review the GitHub comparison for specific changes if migrating from pre-1.0.0 versions.
- gotcha cli-vir requires Node.js version 22 or higher. Running it on older Node.js versions will result in runtime errors due to unsupported syntax or APIs.
- gotcha For correct `binName` detection and automatic exclusion from `process.argv`, you must pass `import.meta` from your top-level executed JavaScript/TypeScript file to the `parseArgs` options. Incorrect usage may lead to `binName` not being resolved correctly or arguments being misinterpreted.
Install
-
npm install cli-vir -
yarn add cli-vir -
pnpm add cli-vir
Imports
- parseArgs
const parseArgs = require('cli-vir').parseArgs;import { parseArgs } from 'cli-vir'; - FlagRequirement
import FlagRequirement from 'cli-vir';
import { FlagRequirement } from 'cli-vir'; - ParsedArgs
import { ParsedArg } from 'cli-vir';import type { ParsedArgs } from 'cli-vir';
Quickstart
import { FlagRequirement, parseArgs } from 'cli-vir';
// Simulate command-line arguments for demonstration
// Example: node my-cli.js --arg1 --arg3 valueA --arg3 valueB arg2Value
const simulatedArgs = ['node', 'my-cli.js', '--arg1', '--arg3', 'valueA', '--arg3', 'valueB', 'arg2Value'];
const myArgs = parseArgs(
simulatedArgs, // In a real CLI, use process.argv
{
arg1: {
flag: {
valueRequirement: FlagRequirement.Blocked,
description: 'A simple boolean flag.'
}
},
arg2: {
required: true,
position: 0,
description: 'A required positional argument.'
},
arg3: {
flag: {
aliases: ['-3'],
allowMultiple: true,
valueRequirement: FlagRequirement.Required,
description: 'A flag that can be provided multiple times.'
}
},
rest: {
position: 'rest',
description: 'Any remaining positional arguments.'
}
},
{
binName: 'my-cli.js', // Or the actual binary name if using a 'bin' entry in package.json
importMeta: import.meta,
},
);
console.log('Parsed Arguments:');
console.log(`arg1: ${myArgs.arg1} (type: ${typeof myArgs.arg1})`); // boolean
console.log(`arg2: ${myArgs.arg2} (type: ${typeof myArgs.arg2})`); // string
console.log(`arg3: ${JSON.stringify(myArgs.arg3)} (type: ${typeof myArgs.arg3})`); // string[]
console.log(`rest: ${JSON.stringify(myArgs.rest)}`); // string[]
// Example: Accessing a non-existent arg will result in a TypeScript error and runtime undefined
// console.log(myArgs.nonExistentArg); // TS Error: Property 'nonExistentArg' does not exist on type '{ arg1: boolean; arg2: string; arg3: string[]; rest: string[]; }'.