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 🙏

© 2025 – Pkg Stats / Ryan Hefner

clibu

v0.1.1

Published

Clibu is a KazVizian lightweight framework for building command-line interfaces.

Readme

Clibu — a modern TypeScript-first CLI builder

TypeScript Bun license

Clibu is a focused, lightweight framework for building command-line interfaces with Bun and Node.js (ESM, Node 18+). It lets you define your entire CLI in a single configuration file—TypeScript, JavaScript, or JSON—while providing precise input validation, predictable help output, and a clean programmatic surface for automation.

This README guides you through installation, configuration, and usage, introduces the core concepts behind Clibu, and covers the APIs you can rely on when embedding it into tools or test suites.

Why Clibu?

Clibu is designed for developers who value clarity, speed, and correctness:

  • Excellent developer experience — Strong TypeScript types help you author and maintain CLIs with confidence.
  • Predictable output — Stable help text and deterministic parsing make testing and CI friction-free.
  • Small, intentional design — A compact API, straightforward concepts, and clear errors keep complexity low.

Clibu emphasizes reliability without sacrificing approachability, making it suitable for both simple utilities and larger toolchains.

Features

  • TypeScript-first configuration and handler context
  • Rich option kinds: flag, string, number, enum with validation (min/max, pattern, choices)
  • Global options with inheritance and controlled overrides
  • Deterministic help rendering, ideal for snapshots
  • Structured, stable error codes
  • Programmatic API for runners, loaders, and help renderers

Install

Install from npm (Node 18+ / ESM):

bun add clibu
# or
pnpm add clibu
# or
npm install clibu
# or
yarn add clibu

Quick start — CLI

Create clibu.config.ts at your project root or point package.json.clibu.configFile at a module/directory (recommended for reuse):

// clibu.config.ts (filename discovery)
import { defineConfig } from "clibu"

export default defineConfig({
  name: "mycli",
  version: "0.0.1",
  commands: {
    hello: {
      description: "Greet the user",
      run(ctx) {
        console.log("hello", ctx.args.join(" "))
      }
    }
  }
})

Run from the project directory:

clibu hello world
clibu --help
clibu hello --help

TypeScript configs are transpiled on demand and cached under .clibu/cache/ using a content hash.

Opt-in alternative via package.json:

{
  "clibu": { "configFile": "./src" }
}

If configFile points to a directory, Clibu tries index.ts|mts|cts|mjs|js|cjs|json before falling back to filename discovery.

[!NOTE]

Type-safety tips:

  • Prefer defineConfig({...}) for rich IntelliSense and immediate type errors in your editor.

  • On TS 4.9+, you can also use the satisfies operator:

    import type { CLIConfig } from "clibu"
    export default {
      /* ... */
    } satisfies CLIConfig

Why Clibu (expanded)

  • Fast iteration — A small, coherent API and strong types help you build CLIs quickly and safely.
  • Test-friendly by design — Deterministic rendering and strict validation enable stable snapshot testing.
  • Explicit configuration — Commands and options are defined through clear schemas, reducing ambiguity and runtime surprises.

Comparison

| Feature / Tool | Clibu | Commander.js | Yargs | Oclif | | ------------------------- | ---------------------------------- | --------------------------- | --------------------------- | ------------------------------- | | Language focus | TypeScript-first (ESM) | JavaScript-first | JavaScript-first | TypeScript-first | | Config style | Single declarative config file | Imperative API | Declarative + builder API | Class-based, plugin-oriented | | Deterministic help | Yes (snapshot-friendly) | Mostly stable | Varies; formatting dynamic | Stable but stylized | | Validation model | Explicit schemas with strict parse | Limited built-in validation | Built-in validation options | Schema-light; validation manual | | Global options | Inheritance with overrides | Manual | Partial support | Supported | | Subcommands | Nested in config | Supported | Supported | Supported (via classes) | | Runtime footprint | Very small | Small | Medium | Larger | | Programmatic API | Minimal, focused | Available | Available | Extensive | | TypeScript experience | Strong types for config & ctx | Community types | Community types | Designed for TS | | Use cases | Tools, utilities, dev CLIs | Simple CLIs | Complex option-heavy CLIs | Large CLI frameworks & plugins |

Core concepts

  • Command — A named unit of work with description, options, optional commands (subcommands), and a run(ctx) handler.
  • Option kindsflag, string, number, enum.
  • Global options — Declared at the root and inherited by default. Inheritance can be disabled (inheritGlobal: false) or overridden per-command.
  • Context (ctx) — Passed to handlers and includes argvRaw, command, args, options, globalOptions, commandOptions, env, and a logger.

Configuration reference

Minimal shape:

export interface CLIConfig {
  name: string
  version?: string
  options?: Record<string, unknown>
  commands: Record<string, CommandDef>
}

Command definition:

interface CommandDef {
  description?: string
  options?: Record<string, OptionSchema>
  commands?: Record<string, CommandDef>
  run?: (ctx: CLIContext) => unknown | Promise<unknown>
  inheritGlobal?: boolean
}

Option schema examples:

{
  verbose: { kind: "flag", alias: "v", description: "Verbose output", default: false },
  threads: { kind: "number", min: 1, max: 8, required: true },
  mode: { kind: "enum", choices: ["dev", "prod"], default: "dev" },
  profile: { kind: "string", pattern: /^[a-z]+$/ }
}

Common metadata: alias, required, default, min, max, integer, minLength, maxLength, pattern, choices, caseSensitive.

Help rendering

Top-level help shows the CLI name, version, usage line, commands, and global options. Command-level help provides the command description, its usage pattern, subcommands (if any), inherited global options, and command-specific options. When no options exist, help clearly indicates (No options).

The renderer is intentionally stable, ensuring clean diffs and predictable CI behavior.

Programmatic usage

A small programmatic surface makes Clibu easy to embed.

Quick runner:

import { run } from "clibu"

const code = await run()
process.exitCode = code

Manual composition:

import { createCLI, loadConfig } from "clibu"

const cfg = await loadConfig(process.cwd())

const cli = createCLI(cfg)
await cli.run(["build"])

Programmatic help:

import { renderHelp, renderCommandHelp } from "clibu"

console.log(renderHelp(cfg))
console.log(renderCommandHelp(cfg, ["build"]))

TypeScript types (CLIConfig, CLIContext, etc.) are exported for convenience.

Loader behavior (config discovery)

Configuration is resolved using the following priority:

  1. Explicit opt-in: package.json.clibu.configFile (file or directory; directory resolves index.ts|mts|cts|mjs|js|cjs|json).
  2. TypeScript: clibu.config.ts, .mts, .cts
  3. JavaScript: clibu.config.mjs, .js, .cjs
  4. JSON: clibu.config.json

When importing a module, Clibu prefers export const config = {} and falls back to export default {}. TypeScript files are compiled into .clibu/cache/<hash>.mjs (or .cjs for .cts) to optimize repeated runs.

Implementation notes

  • Loader & TS transpilation: packages/loader/src/index.ts
  • Core engine: packages/core/src/*
  • Deterministic help rendering: packages/help/src/index.ts

Parsing and option semantics

Clibu uses a two-phase parsing strategy:

  • Relaxed scan (discovery) — Identifies the command path, ignoring unknown options so users can mix global flags freely.
  • Strict parse (validation) — Once the command is resolved, remaining tokens are validated against the merged option schema. Unknown options and duplicates raise a ParsingError (E_PARSE).

Supported token forms:

  • Long: --name, --name=value
  • Boolean negation: --no-<name>
  • Short aliases and clusters: e.g., -abc

Merging and overriding

  • Command-level options override global ones by name.
  • Alias conflicts or kind mismatches trigger E_OPTION_CONFLICT.
  • inheritGlobal: false disables inheritance entirely.

Option schema extras

  • Flags support negate?: boolean (default true)
  • Enums support caseSensitive?: boolean (default false)

Programmatic API (exports)

From the clibu facade:

  • run(cwd?, argv?): Promise<number>
  • createCLI(config: CLIConfig)
  • loadConfig(cwd: string)
  • renderHelp(cfg)
  • renderCommandHelp(cfg, path)

Plugin system (Organs)

Clibu provides a lightweight extension mechanism called organs. An organ is a small, self-contained plugin that can observe or augment CLI behavior at key lifecycle points without interfering with core guarantees such as correctness and deterministic parsing.

Organs are intentionally minimal. They allow tooling authors to integrate logging, metrics, environment preparation, or other cross-cutting concerns in a controlled way.

Key elements

  • ClibuOrgan — the plugin interface. Typical hooks include:

    • name: string and optional version
    • onRegister(config) — invoked when a configuration object is loaded or attached
    • onParse(argv) — triggered during the relaxed parsing phase
    • onBeforeRun(ctx) — executed before a command handler starts (supports async)
    • onAfterRun(ctx, result) — executed after a handler completes (supports async)
    • extendConfig(config) — optionally returns a modified configuration for advanced scenarios
  • OrganManager — a small utility that registers organs and emits lifecycle events. It is available through the public Clibu API.

Usage example

To integrate organ behavior into a custom runner, use the low-level APIs together with OrganManager:

import { loadConfig, buildContext, OrganManager } from "clibu"

const argv = process.argv.slice(2)
const cfg = await loadConfig(process.cwd())
if (!cfg) throw new Error("No config found")

const organs = new OrganManager()

// Register custom organs
organs.register({
  name: "my-organ",
  onRegister(cfg) {
    // inspect or log
  },
  onBeforeRun(ctx) {
    // prepare resources
  }
})

// Emit lifecycle events
organs.emitRegister(cfg)
organs.emitParse(argv)

// Build execution context (resolves command and parses options)
const ctx = buildContext(cfg, argv)

// Run lifecycle hooks around the actual command
await organs.emitBeforeRun(ctx)
const result = await ctx.command.target.run?.(ctx)
await organs.emitAfterRun(ctx, result)

Notes & guidance

  • Organs are opt-in and not automatically wired into the high-level run() helper. To involve organs in the full lifecycle, use the lower-level composition APIs shown above.
  • Organ hooks should remain fast and predictable. onBeforeRun and onAfterRun support asynchronous operations, making them suitable for tasks such as telemetry, setup/teardown, or environment checks.
  • extendConfig is intended for advanced use cases. Because it can alter command resolution and validation, use it sparingly and keep transformed configurations transparent and traceable.

Errors and stable codes

Clibu surfaces domain-specific errors with stable codes:

  • E_PARSE — Unknown option, malformed value, invalid token
  • E_VALIDATE — Failed validation rules
  • E_COMMAND_NOT_FOUND
  • E_OPTION_CONFLICT

--version / -V prints <name> <version>.

FAQ & troubleshooting

  • “No configuration file found.” Ensure a valid clibu.config.* exists OR set package.json.clibu.configFile pointing to a module/directory (directory resolves index.*). TypeScript files are auto-transpiled.

  • “Command has no run() handler.” Provide a run(ctx) function or execute a subcommand that defines one.

  • “Alias collision or kind mismatch.” Rename the option or disable global inheritance.

  • Using CommonJS? Clibu is ESM-first. For programmatic usage from CJS, wrap your call with a dynamic import().

Contributing

Clibu aims to remain compact, reliable, and pleasant to use. Contributions are welcome, with a focus on:

  • Keeping help output deterministic
  • Adding thorough tests for parsing and validation
  • Preserving API stability

License

MIT © KazViz