Build a CLI in 5 lines. The fastest way to turn a script into a CLI tool.
import { cli } from "@munesoft/clix";
cli({
greet: (name) => `Hello ${name}`
});node app.js greet John
# Hello JohnMost CLI frameworks require boilerplate setup, config files, and long tutorials before you can run anything. clix takes a different approach: just map command names to functions and you're done.
| Feature | clix | commander | yargs | oclif |
|---|---|---|---|---|
| Lines to first command | 3 | ~15 | ~10 | ~30+ |
| Zero config | ✅ | ❌ | ❌ | ❌ |
| Auto-generated help | ✅ | ✅ | ✅ | ✅ |
| Async commands | ✅ | ✅ | ✅ | ✅ |
| TypeScript-first | ✅ | ✅ | ✅ | |
| ESM + CJS | ✅ | ✅ | ✅ | |
| Subcommands | ✅ | ✅ | ✅ | ✅ |
| Setup time | <2 min | ~10 min | ~10 min | ~30 min |
npm install @munesoft/clixCreate app.js:
import { cli } from "@munesoft/clix";
cli({
greet: (name) => `Hello ${name}`,
add: (a, b) => Number(a) + Number(b),
});Run it:
node app.js greet Alice # Hello Alice
node app.js add 5 10 # 15
node app.js --help # auto-generated helpThat's it. No setup. No config. No program.command().argument().action().
cli({
// String output
say: (msg) => msg,
// Math
add: (a, b) => Number(a) + Number(b),
// Object output (pretty-printed as JSON)
info: () => ({ node: process.version, platform: process.platform }),
});Flags are passed as the last argument to your function:
cli({
say: (msg, flags) => flags.loud ? msg.toUpperCase() : msg,
});node app.js say hello # hello
node app.js say hello --loud # HELLO
node app.js serve --port=3000 # flags.port === 3000
node app.js serve --port 8080 # flags.port === 8080
node app.js run --debug # flags.debug === truecli({
fetch: async (url) => {
const res = await fetch(url);
return res.text();
},
delay: async (ms) => {
await new Promise(r => setTimeout(r, Number(ms)));
return "done";
},
});cli({
// Space-separated subcommands
"user create": (name) => `Created user: ${name}`,
"user delete": (id) => `Deleted user: ${id}`,
// Or dot/colon notation
"db.migrate": () => runMigrations(),
"db:seed": () => seedDatabase(),
});node app.js user create Alice
node app.js db.migrateimport { cli, describe } from "@munesoft/clix";
cli({
greet: describe("Greet a user by name", (name) => `Hello ${name}`),
add: describe("Add two numbers", (a, b) => Number(a) + Number(b)),
});cli(
{ greet: (name) => `Hello ${name}` },
{ aliases: { hi: "greet", hello: "greet" } }
);node app.js hi Alice # Hello Alice
node app.js hello Alice # Hello Alicecli(commands, {
name: "my-tool",
version: "1.0.0",
description: "My awesome CLI tool",
});node app.js --version # 1.0.0
node app.js --help # shows name, version, descriptioncli(commands, {
formatter: (result) => {
if (typeof result === "object") {
return `Result: ${JSON.stringify(result)}`;
}
return String(result);
},
});Running --help (or -h) automatically generates clean help from your commands:
my-tool v1.0.0
My awesome CLI tool
Usage:
node app.js <command> [args] [--flags]
Available commands:
greet <name> Greet a user by name
add <a> <b> Add two numbers
fetch <url>
Global flags:
--help Show this help message
--version Show version number
No registration needed — clix reads your function parameter names automatically.
Unknown commands produce clean, actionable errors:
❌ Unknown command: xyz
Try: node app.js --help
Errors thrown by your commands are caught and displayed without crashing:
❌ Failed to connect: ECONNREFUSED
Add --verbose (or -v) to get the full stack trace.
clix is written in TypeScript and ships full type definitions:
import { cli, CliOptions, CommandMap } from "@munesoft/clix";
const commands: CommandMap = {
greet: (name: string) => `Hello ${name}`,
};
const options: CliOptions = {
name: "greeter",
version: "1.0.0",
};
cli(commands, options);Bootstraps the CLI. Reads process.argv, matches the command, and executes it.
| Parameter | Type | Description |
|---|---|---|
commands |
Record<string, Function> |
Map of command names to handler functions |
options.name |
string |
CLI display name |
options.version |
string |
Version string (enables --version) |
options.description |
string |
Short description for help output |
options.aliases |
Record<string, string> |
Alias map { alias: "target" } |
options.formatter |
(result) => string |
Custom output formatter |
options.exit |
(code) => void |
Custom exit handler |
Attaches a description to a command function for display in --help.
Synchronous wrapper around cli() for environments that cannot use top-level await.
Low-level argument parser. Returns { command, args, flags, raw }.
Scripts — Turn one-off scripts into proper tools:
cli({ backup: () => runBackup(), restore: (file) => runRestore(file) });Automation — Build internal automation tools in minutes:
cli({
deploy: async (env) => deploy(env),
rollback: async (version) => rollback(version),
status: async () => getStatus(),
});Dev tools — Package developer utilities:
cli({
"db seed": () => seed(),
"db migrate": () => migrate(),
"db reset": () => reset(),
lint: () => runLint(),
test: (pattern) => runTests(pattern),
});MIT © Munesoft