Citty CLI Builder

0.2.2 · active · verified Wed Apr 22

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.

Common errors

Warnings

Install

Imports

Quickstart

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);

view raw JSON →