{"id":29905413,"url":"https://github.com/ghiscoding/cli-nano","last_synced_at":"2025-08-01T19:13:46.147Z","repository":{"id":301097554,"uuid":"1008131103","full_name":"ghiscoding/cli-nano","owner":"ghiscoding","description":"small tool to create command-line tool (CLI) similar to Yargs or NodeJS `parseArgs()`","archived":false,"fork":false,"pushed_at":"2025-07-25T19:29:36.000Z","size":203,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-26T02:19:19.879Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ghiscoding.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-25T04:43:43.000Z","updated_at":"2025-07-25T19:29:40.000Z","dependencies_parsed_at":"2025-06-25T13:54:21.021Z","dependency_job_id":null,"html_url":"https://github.com/ghiscoding/cli-nano","commit_stats":null,"previous_names":["ghiscoding/micro-cli","ghiscoding/microcli","ghiscoding/minicli","ghiscoding/cli-nano"],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/ghiscoding/cli-nano","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghiscoding%2Fcli-nano","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghiscoding%2Fcli-nano/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghiscoding%2Fcli-nano/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghiscoding%2Fcli-nano/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ghiscoding","download_url":"https://codeload.github.com/ghiscoding/cli-nano/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ghiscoding%2Fcli-nano/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268282365,"owners_count":24225164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-01T02:00:08.611Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-08-01T19:13:45.538Z","updated_at":"2025-08-01T19:13:46.137Z","avatar_url":"https://github.com/ghiscoding.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)\n[![Vitest](https://img.shields.io/badge/tested%20with-vitest-fcc72b.svg?logo=vitest)](https://vitest.dev/)\n[![codecov](https://codecov.io/gh/ghiscoding/cli-nano/branch/main/graph/badge.svg)](https://codecov.io/gh/ghiscoding/cli-nano)\n[![npm](https://img.shields.io/npm/v/cli-nano.svg)](https://www.npmjs.com/package/cli-nano)\n[![npm](https://img.shields.io/npm/dy/cli-nano)](https://www.npmjs.com/package/cli-nano)\n[![npm bundle size](https://img.shields.io/bundlephobia/minzip/cli-nano?color=success\u0026label=gzip)](https://bundlephobia.com/result?p=cli-nano)\n\u003ca href=\"https://nodejs.org/en/about/previous-releases\"\u003e\u003cimg src=\"https://img.shields.io/node/v/cli-nano.svg\" alt=\"Node\" /\u003e\u003c/a\u003e\n\n## cli-nano\n\nSmall library to create command-line tool (aka CLI) which is quite similar to [`Yargs`](https://github.com/yargs/yargs), it is as configurable as Yargs but is a fraction of its size. The library is also inspired by NodeJS `parseArgs()` but is a lot more configurable in order to get what we would expect from a more complete CLI builder tool.\n\n### Features\n- Parses arguments\n- Supports defining Positional (input) arguments\n  - Supports Variadic args (1 or more positional args)\n- Automatically converts flags to camelCase to match config options\n  - accepts both `--camelCase` and `--kebab-case`\n- Negates flags when using the `--no-` prefix\n- Outputs version, when defined, by using `--version`\n- Outputs description and supplied help text by using `--help`\n- Supports defining `required` options\n- Supports `default` values\n- Supports `group` for grouping command options in help\n- No dependencies!\n\n### Install\n```sh\nnpm install cli-nano\n```\n\n### Usage\n\n```ts\n#!/usr/bin/env node\n\nimport { type Config, parseArgs } from 'cli-nano';\n\nconst config: Config = {\n  command: {\n    name: 'serve',\n    describe: 'Start a server with the given options',\n    examples: [\n      { cmd: '$0 ./www/index.html 8080 --open', describe: 'Start web server on port 8080 and open browser' },\n      {\n        cmd: '$0 ./index.html 8081 --no-open --verbose',\n        describe: 'Start web server on port 8081 without opening browser and print more debugging logging to the console',\n      },\n    ],\n    positionals: [\n      {\n        name: 'input',\n        describe: 'serving files or directory',\n        type: 'string',\n        variadic: true, // 1 or more\n        required: true,\n      },\n      {\n        name: 'port',\n        type: 'number',\n        describe: 'port to bind on',\n        required: false,\n        default: 5000, // optional default value\n      },\n    ],\n  },\n  options: {\n    dryRun: {\n      alias: 'd',\n      type: 'boolean',\n      describe: 'Show what would be done, but do not actually start the server',\n      default: false, // optional default value\n    },\n    display: {\n      group: 'Advanced Options',\n      alias: 'D',\n      required: true,\n      type: 'boolean',\n      describe: 'a required display option',\n    },\n    exclude: {\n      alias: 'e',\n      type: 'array',\n      describe: 'pattern or glob to exclude (may be passed multiple times)',\n    },\n    verbose: {\n      alias: 'V',\n      type: 'boolean',\n      describe: 'print more information to console',\n    },\n    open: {\n      alias: 'o',\n      type: 'boolean',\n      describe: 'open browser when starting server',\n      default: true,\n    },\n    cache: {\n      type: 'number',\n      describe: 'Set cache time (in seconds) for cache-control max-age header',\n      default: 3600,\n    },\n    address: {\n      type: 'string',\n      describe: 'Address to use',\n      required: true,\n    },\n    rainbow: {\n      group: 'Advanced Options',\n      type: 'boolean',\n      alias: 'r',\n      describe: 'Enable rainbow mode',\n      default: true,\n    },\n  },\n  version: '0.1.6',\n  helpFlagCasing: 'camel',  // show help flag option in which casing (camel/kebab) (defaults to 'kebab')\n  helpDescMinLength: 40,    // min description length shown in help (defaults to 50)\n  helpDescMaxLength: 120,   // max description length shown in help (defaults to 100), will show ellipsis (...) when greater\n  helpUsageSeparator: ':',  // defaults to \"→\"\n};\n\nconst args = parseArgs(config);\nconsole.log(args);\n\n// do something with parsed arguments, for example\n// const { input, port, open } = args;\n// startServer({ input, port, open });\n```\n\n### Usage with Type Inference\n\nFor full TypeScript auto-inference and intelliSense of parsed arguments, define your config as a `const` and cast it `as const`:\n\n```ts\nconst config = {\n  ... // your config object as shown above\n} as const;\n\nconst args = parseArgs\u003ctypeof config\u003e(config);\n\n// TypeScript will infer the correct types:\nargs.input;   // [string, ...string[]] (required, variadic)\nargs.port;    // number   (optional, has default)\nargs.verbose; // boolean  (optional)\nargs.display; // boolean (required)\n```\n\n\u003e **Tip:**  \n\u003e Using `as const` preserves literal types and tuple information, so TypeScript can infer required/optional fields and argument types automatically.  \n\u003e If you use `const config: Config = { ... }`, you get type checking but not full intelliSense for parsed arguments.\n\n\u003e [!NOTE]\n\u003e For required+variadic positionals, the type is `[string, ...string[]]` (at least one value required). For optional variadic, it's `string[]`. For non-variadic, it's `string`.\n\n#### Example CLI Calls\n\n```sh\n# Show help guide (created by reading CLI config)\nserve --help\n\n# Show version (when defined)\nserve --version\n\n# Uses default port 5000\nserve dist/index.html\n\n# With required and optional positionals\nserve index1.html index2.html 8080 -D value\n\n# With boolean and array options entered as camelCase (kebab-case works too)\nserve index.html 7000 --dryRun --exclude pattern1 --exclude pattern2 -D value\n\n# With negated boolean entered as kebab-case\nserve index.html 7000 --no-dryRun -D value\n\n# With short aliases (case sensitive)\nserve index.html 7000 -d -e pattern1 -e pattern2 -D value\n\n# With number option\nserve index.html 7000 --up 2 -D value\n```\n\n#### Notes\n\n- **Default values**: Use the `default` property in an option or positional argument to specify a value when the user does not provide one.\n  - Example for option: `{ type: 'boolean', default: false }`\n  - Example for positional: `{ name: 'port', type: 'number', default: 5000 }`\n- **Variadic positionals**: Use `variadic: true` for arguments that accept multiple values.\n- **Required options**: Add `required: true` to enforce presence of an option.\n- **Negated booleans**: Use `--no-flag` to set a boolean option to `false`.\n- **Array options**: Repeat the flag to collect multiple values (e.g., `--exclude a --exclude b`).\n- **Aliases**: Use `alias` for short flags (e.g., `-d` for `--dryRun`).\n- **Groups**: Use `group` for grouping some commands in help (e.g., `{ group: 'Extra Commands' }`).\n\nSee [examples/](examples/) for more usage patterns.\n\n## Used by\n\n`cli-nano` is currently used in these other projects of mine (feel free to edit this list):\n\n- [native-copyfiles](https://github.com/ghiscoding/native-copyfiles)\n- [remove-glob](https://github.com/ghiscoding/remove-glob)\n\n## Help Example\n\nYou can see below an example of a CLI help (which is the result of calling `--help` with the [config](#usage) shown above). \n\nPlease note:\n\n- `\u003coption\u003e` → required\n- `[option]` → optional\n\n```\nUsage:\n  serve \u003cinput..\u003e [port] [options] → Start a server with the given options\n\nExamples:\n  serve ./www/index.html 8080 --open → Start web server on port 8080 and open browser\n  serve ./index.html 8081 --no-open --verbose → Start web server on port 8081 without opening browser and print more debugging logging to the console\n\nArguments:\n  input           serving files or directory                                      \u003cstring..\u003e\n  port            port to bind on                                                 [number]\n\nOptions:\n  -d, --dry-run   Show what would be done, but do not actually start the server   [boolean]\n  -e, --exclude   pattern or glob to exclude (may be passed multiple times)       [array]\n  -V, --verbose   print more information to console                               [boolean]\n  -o, --open      open browser when starting server                               [boolean]\n      --cache     Set cache time (in seconds) for cache-control max-age header    [number]\n      --address   Address to use                                                  \u003cstring\u003e\n  -h, --help      Show help                                                       [boolean]\n  -v, --version   Show version number                                             [boolean]\n\nAdvanced Options:\n  -D, --display   a required display option                                       \u003cboolean\u003e\n  -r, --rainbow   Enable rainbow mode                                             [boolean]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghiscoding%2Fcli-nano","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fghiscoding%2Fcli-nano","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fghiscoding%2Fcli-nano/lists"}