Tiny CLI Argument Parser

raw JSON →
1.2.2 verified Thu Apr 23 auth: no javascript

cli-nano is a lightweight library for building command-line interfaces (CLIs) in Node.js, offering functionality similar to `yargs` or Node.js's built-in `parseArgs()`. It supports parsing positional arguments, flags, and options with robust configuration capabilities. The current stable version is 1.2.2, with releases occurring fairly frequently, often including minor bug fixes and features, sometimes with breaking changes within minor versions as seen with v1.2.0 and v1.0.0. Its key differentiators include a minimal footprint, zero external dependencies, and extensive configurability for defining argument types, aliases, defaults, and generating help output, making it a powerful alternative to heavier CLI libraries while providing more features than the native `parseArgs()` method. It is designed for Node.js environments and ships with TypeScript types for enhanced developer experience.

error Error: Missing required argument: input
cause A required positional argument or option was not provided on the command line.
fix
Ensure all required: true arguments and options are supplied when running the CLI. For example, if 'input' is required, run your-cli-command 'some-value'.
error Error: Expected option 'port' to be of type 'number', but received 'abc'
cause An option was provided with a value that does not match its defined `type` (e.g., passing a string where a number is expected).
fix
Provide values that match the expected type for each option. For a number type, ensure a valid numeric string is passed (e.g., --port 8080, not --port abc).
error Error: Unknown option: --unknown-flag
cause The CLI was invoked with an option or flag that was not defined in the `config.options` object.
fix
Check for typos in the flag name or define the option in your parseArgs configuration. If it's an intended flag, add it to config.options with its type and description.
breaking The `positionals` configuration property changed from an array of positional argument definitions to an object where keys are the positional argument names. This requires updating how positional arguments are defined in your CLI configuration.
fix Update `command.positionals` from `[{ name: 'arg', ... }]` to `{ arg: { ... } }`.
breaking The `description` property within the command configuration was renamed to `describe` to align with `Yargs`'s terminology and conventions. Using the old `description` property will no longer have an effect.
fix Change `command.description` to `command.describe` in your CLI configuration.
breaking The property for defining positional arguments was changed from `positional` (singular) to `positionals` (plural). If you were using the singular form, your configuration will no longer be correctly interpreted.
fix Rename the `positional` property in your command configuration to `positionals`.
gotcha cli-nano defaults to camelCase for converting kebab-case flags (e.g., `--my-flag` becomes `myFlag`). While it accepts both, ensure your code accesses options using the camelCase variant unless `helpFlagCasing` is explicitly set to `kebab`.
fix Always access parsed options using their camelCase equivalent (e.g., `args.myFlag`). If you need kebab-case for help display, set `helpFlagCasing: 'kebab'` in your config, but this does not change the parsed argument key.
npm install cli-nano
yarn add cli-nano
pnpm add cli-nano

This quickstart demonstrates how to define a CLI command with positional arguments, various options (booleans, numbers, strings, arrays), aliases, default values, and a version/help display. It then parses `process.argv` and logs the results, showcasing basic argument access and conditional logic based on flags.

import { parseArgs } from 'cli-nano';

const main = async () => {
  const config = {
    command: {
      name: 'serve',
      describe: 'Start a server with the given options',
      examples: [
        { cmd: '$0 ./www/index.html 8080 --open', describe: 'Start web server on port 8080' }
      ],
      positionals: [
        { name: 'input', describe: 'serving files or directory', type: 'string', variadic: true, required: true },
        { name: 'port', type: 'number', describe: 'port to bind on', required: false, default: 5000 }
      ]
    },
    options: {
      dryRun: { alias: 'd', type: 'boolean', describe: 'Show what would be executed', default: false },
      verbose: { alias: 'V', type: 'boolean', describe: 'print more information to console' },
      open: { alias: 'o', type: 'boolean', describe: 'open browser when starting server', default: true },
      address: { type: 'string', describe: 'Address to use', required: true, default: '127.0.0.1' }
    },
    version: '1.2.2',
    helpFlagCasing: 'camel'
  };

  try {
    const args = parseArgs(config);
    if (args) {
      console.log('Parsed Arguments:', args);
      console.log(`Serving '${args.input.join(', ')}' on ${args.address}:${args.port}`);
      if (args.dryRun) {
        console.log('This is a dry run. Server would not actually start.');
      } else if (args.open) {
        console.log('Opening browser...');
      }
    }
  } catch (error) {
    console.error('CLI Error:', (error as Error).message);
  }
};

main();