Zero-dependency, batteries-included CLI framework for Node.js / TypeScript.
Define a command once and it works two ways: as myapp deploy prod typed at a shell, and as deploy prod typed at your tool's own interactive prompt. Around that sit the parts a command-line tool usually needs — options, subcommands, tab completion, colour, tables, progress bars, prompts and a logger — with no runtime dependencies to install.
- Commands, subcommands, aliases, and typed options with defaults, choices and validation
- An interactive shell with persistent history, tab completion, pipes, and mode sub-REPLs
- Colour, tables, progress bars, spinners, prompts and a logger, each usable on its own
- Lifecycle events and plugins for cross-cutting behaviour
- TypeScript and ESM first, no production dependencies
Node.js 22 or later, ESM only.
npm install @libraz/node-cli#!/usr/bin/env node
import { createCLI } from "@libraz/node-cli";
const cli = createCLI({ name: "myapp", version: "1.0.0" });
cli
.command("greet <name>")
.description("Greet someone")
.option("-u, --uppercase", { type: "boolean" })
.action((ctx) => {
const name = ctx.args.name as string;
ctx.stdout.write(`Hello, ${ctx.options.uppercase ? name.toUpperCase() : name}!\n`);
});
await cli.start();Run it with arguments and it executes one command and exits:
$ myapp greet World --uppercase
Hello, WORLD!Run it with none, from a terminal, and the same command is available at an interactive prompt:
$ myapp
myapp v1.0.0
> greet World
Hello, World!
> exitGetting started covers the rest of the setup — the bin entry, the build step, and making myapp available on your path.
Start with Introduction for the mental model, or Getting started to build a working tool end to end. New to command-line development? The glossary defines every term the docs use.
| Topic | Pages |
|---|---|
| Building commands | Commands · Options · Errors |
| The interactive shell | Interactive shell |
| Output | Colour · Tables · Progress · Prompts · Logging |
| Extending | Events and plugins |
| Reference | API reference · Examples · Glossary |
Ten runnable examples live in examples/.
- ESM only. There is no CommonJS build;
require("@libraz/node-cli")will not work. - No shell completion scripts. Tab completion works inside the tool's own interactive shell. Completion for bash, zsh or fish is not generated.
- No configuration-file loading. Reading a config file, merging it with options, and resolving precedence is left to the application.
- No positional-argument coercion. Positional arguments arrive as strings; types, defaults and choices exist on options only.
- Built-in messages are English. Help output and error text are not translated.