Registry / devops / citty
library0.0.3jsnpmunverified

citty is a modern, elegant, and highly performant CLI builder for Node.js, currently stable at version `0.2.2`. It distinguishes itself by being entirely zero-dependency since `v0.2.0`, leveraging Node.js's native `util.parseArgs` for its core argument parsing. This design choice results in a significantly reduced install size (from 267kB to 22.8kB as of `v0.2.0`) and fast execution, making it an excellent choice for lightweight command-line tools. `citty` provides a flexible and composable API that supports nested sub-commands, complete with options for lazy and asynchronous loading, which is crucial for building large-scale CLIs without incurring heavy startup costs. Recent enhancements in `v0.2.2` introduced a robust plugin system, allowing developers to extend command functionality with reusable `setup` and `cleanup` hooks. It also offers smart value parsing, type casting, boolean shortcuts, and automatically generates comprehensive usage information. The project maintains an active release cadence, frequently adding new features and addressing issues, demonstrating its ongoing development and commitment to a stable and feature-rich experience.

npm install citty
INSTALL
IMPORT
SIG · CITTY
C
citty
devopsjavascriptv0.0.3
Install
—
Import
—
Disk
—
Pass rate
0/ 6
Env Coverage0 / 6
glibc
18–22
musl
18–22
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18–226 runs
build_error
glibc
node 18–226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

defineCommand
✓ import { defineCommand } from 'citty'
✗ const { defineCommand } = require('citty')
While CommonJS `require` might work in some setups, ESM `import` is the primary and recommended usage, especially in modern Node.js CLI projects.
runMain
✓ import { runMain } from 'citty'
✗ const { runMain } = require('citty')
This function is the entry point for executing your Citty CLI application. Ensure your main script is configured as an ESM module.
defineCittyPlugin
✓ import { defineCittyPlugin } from 'citty'
✗ const { defineCittyPlugin } = require('citty')
Introduced in `v0.2.2`, `defineCittyPlugin` is used for creating reusable command plugins. Requires `v0.2.2` or newer.

This example demonstrates how to define a main command with positional and optional arguments, including `setup`, `run`, and `cleanup` hooks. It shows basic argument parsing and execution flow.

import { defineCommand, runMain } from 'citty'; // Define a simple command with a positional argument and an optional boolean flag const mainCommand = defineCommand({ meta: { name: 'greeter-app', version: '1.0.0', description: 'A simple CLI application to greet users based on arguments.' }, args: { name: { type: 'positional', description: 'The name of the person to greet. This argument is required.', required: true, valueHint: '<your-name>' }, friendly: { type: 'boolean', description: 'Use a friendly greeting like \'Hi\' instead of \'Greetings\'.', default: false }, repeat: { type: 'string', description: 'Specify how many times to repeat the greeting.', default: '1' } }, setup({ args }) { console.log(`[SETUP] Initializing greeter for command: ${this.meta.name}`); if (isNaN(Number(args.repeat))) { console.error("Warning: 'repeat' argument must be a number. Defaulting to 1."); args.repeat = "1"; // Ensure it's a number for run() } }, async run({ args }) { const greeting = args.friendly ? 'Hi' : 'Greetings'; const repeatCount = Number(args.repeat); for (let i = 0; i < repeatCount; i++) { console.log(`${greeting} ${args.name}!`); } }, cleanup({ args }) { console.log(`[CLEANUP] Finished greeting ${args.name} ${args.repeat} time(s).`); } }); // Run the main command. This should be the entry point of your CLI. // Example usage: node cli.mjs John --friendly --repeat 3 runMain(mainCommand);
citty --version
Debug
Known issues
gotchaStarting with `v0.2.0`, citty transitioned to a zero-dependency architecture by leveraging Node.js's native `util.parseArgs`. While this significantly reduces bundle size and improves performance, it might subtly alter argument parsing behavior compared to previous versions that relied on third-party dependencies.
fix
Review your CLI argument parsing logic, especially for edge cases or complex argument structures, if upgrading from versions prior to `v0.2.0`. This change generally simplifies the dependency graph.
affects: >=0.2.0
gotchaPrior to `v0.2.2`, handling user-defined arguments for common flags like `-h`, `--help`, `-v`, and `--version` could be unreliable or lead to unexpected behavior, as citty might implicitly handle these. User-defined arguments for these specific flags were not consistently respected.
fix
Upgrade to `v0.2.2` or higher. This version includes a fix that properly allows users to define and override these arguments within their command's `args` configuration, ensuring consistent behavior.
affects: <0.2.2
gotchaFeatures such as subcommand aliases, default subcommands, and the plugin system were introduced or significantly enhanced in `v0.2.2`. Codebases relying on custom workarounds for these functionalities or attempting to use them in earlier versions might encounter errors or unexpected behavior.
fix
For full support and expected behavior of subcommand aliases, default subcommands, and the plugin system, ensure you are using `citty@0.2.2` or newer. Refactor any custom logic to utilize the new official APIs.
affects: <0.2.2
Errors
Common errors & fixes
Cannot find module 'citty'
The `citty` package is not installed in your project, or your Node.js environment cannot resolve ESM imports correctly.
fix
Run `npm install citty` or `yarn add citty`. Ensure your package.json `type` is set to `module` or your file uses the `.mjs` extension for ESM imports.
Error: Missing required argument: <arg_name>
A command was executed without providing a value for an argument explicitly marked as `required: true` in its definition.
fix
Ensure all required positional or named arguments are supplied on the command line. For example, if 'name' is required, run `your-cli <value_for_name>`.
Unknown argument: --invalid-option
The CLI received an argument or option that was not explicitly defined in the `args` configuration for the executed command or any of its subcommands.
fix
Either define the argument in your command's `args` object with the correct type, or remove the unknown argument from the CLI call.
TypeError: Cannot read properties of undefined (reading 'meta') or (reading 'run')
This often occurs when a subcommand is expected to be a `Command` object but is instead `undefined` or a `Promise` that hasn't resolved, especially with lazy loading or incorrect dynamic imports.
fix
Verify that lazy-loaded subcommands correctly return the default export of a `defineCommand` result. Ensure promises for `Resolvable<T>` types are awaited or handled correctly, particularly in `subCommands` configurations.
Upgrade
Version history
0.0.3latest on npm
Audit
Dependencies

No dependency data recorded yet.

Agent activity
26 hits · last 30 days
node
20
Amazon
1
OpenAI (training)
1
Resources