npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@munesoft/clix

v1.0.1

Published

The fastest way to turn a script into a CLI. Zero boilerplate, intuitive API, clean output.

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 John

Why 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/clix

Quickstart

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 help

That'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 === true

Async 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.migrate

Command 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 Alice

Global 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, description

Custom 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 number

No registration needed — clix reads your function parameter names automatically.


Error Handling

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.


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