Type-Safe CLI Framework

4.0.0-rc.4 · active · verified Sun Apr 19

Clipanion is a TypeScript-first framework for building robust and type-safe command-line interfaces (CLIs). It leverages TypeScript's powerful type system to define command arguments and options, providing compile-time validation and autocompletion, significantly reducing common runtime errors associated with CLI parsing. The package is currently at version `4.0.0-rc.4`, indicating active development towards a stable major release with a strong emphasis on modern JavaScript and TypeScript practices. A key differentiator is its zero runtime dependencies (beyond its peer dependency `typanion` for runtime type validation), resulting in extremely small bundle sizes. It integrates deeply with `typanion` to derive runtime validators directly from static TypeScript types, providing a seamless development experience for complex CLI applications. This approach contrasts with other CLI libraries that often rely on separate schema definitions or less integrated type checking.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates a basic Clipanion CLI with a 'hello' command, utilizing `Option.String` for argument parsing with a default value and integrating built-in help and version commands. It showcases the ESM-first approach and the use of `Command.String()` for validation.

import { Cli, Command, Option, Builtins } from 'clipanion';
import process from 'node:process';

class HelloCommand extends Command {
  static paths = [['hello'], ['hi']];

  name = Option.String('--name', { 
    description: 'Name to greet',
    required: false,
    validator: Command.String().withDefault('World')
  });

  async execute() {
    this.context.stdout.write(`Hello, ${this.name}!\n`);
  }
}

async function main() {
  const cli = new Cli({
    binaryLabel: `My CLI App`,
    binaryName: `my-cli`,
    binaryVersion: `1.0.0`,
  });

  cli.register(HelloCommand);
  cli.register(Builtins.VersionCommand);
  cli.register(Builtins.HelpCommand);
  
  await cli.run(process.argv.slice(2), { 
    cwd: process.cwd(),
    stdout: process.stdout,
    stdin: process.stdin,
    stderr: process.stderr,
    env: process.env,
  });
}

main().catch(err => {
  console.error('CLI Error:', err);
  process.exit(1);
});

view raw JSON →