@munesoft/clix
v1.0.1
Published
The fastest way to turn a script into a CLI. Zero boilerplate, intuitive API, clean output.
Maintainers
Readme
@munesoft/clix
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 JohnWhy clix?
Most 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 |
Installation
npm install @munesoft/clixQuickstart
Create 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().
Command Examples
Basic commands
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 and options
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 === trueAsync commands
cli({
fetch: async (url) => {
const res = await fetch(url);
return res.text();
},
delay: async (ms) => {
await new Promise(r => setTimeout(r, Number(ms)));
return "done";
},
});Subcommands
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.migrateCommand descriptions (shown in --help)
import { 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)),
});Aliases
cli(
{ greet: (name) => `Hello ${name}` },
{ aliases: { hi: "greet", hello: "greet" } }
);node app.js hi Alice # Hello Alice
node app.js hello Alice # Hello AliceGlobal options
cli(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, descriptionCustom output formatter
cli(commands, {
formatter: (result) => {
if (typeof result === "object") {
return `Result: ${JSON.stringify(result)}`;
}
return String(result);
},
});Auto Help Generator
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 numberNo registration needed — clix reads your function parameter names automatically.
Error Handling
Unknown commands produce clean, actionable errors:
❌ Unknown command: xyz
Try: node app.js --helpErrors thrown by your commands are caught and displayed without crashing:
❌ Failed to connect: ECONNREFUSEDAdd --verbose (or -v) to get the full stack trace.
TypeScript
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);API Reference
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 |
describe(description, fn)
Attaches a description to a command function for display in --help.
cliSync(commands, options?)
Synchronous wrapper around cli() for environments that cannot use top-level await.
parseArgs(argv)
Low-level argument parser. Returns { command, args, flags, raw }.
Use Cases
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),
});License
MIT © Munesoft
