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

concise-ti

v0.1.0-rc.3

Published

Concise Terminal Interface

Readme

Concise Terminal Interface is a lightweight, dependency-free, Bun-native TypeScript framework for building command-line tools. Install it as a dependency, call it once from your entrypoint, and start writing command files. The tool automatically discovers them, parses their arguments, routes to them, and renders their output.

Vision

Managing a command-line interface should feel like working with Next.js, not starting with a boilerplate kit. Install concise-ti and you're ready to go. Write an entrypoint that's one line long, drop files into a /commands directory, and you have a working, typed, compilable CLI. Everything between the argument vector and your handler is concise-ti's job, not yours.

There are no configuration files and no wiring code to handle. The framework handles all the plumbing.

                 ┌───────────────────────────┐
   argv    ───►  │   run(config, meta)       │
                 │   The only line you write │
                 └────────────┬──────────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
        Resolve route   Parse & coerce   Build context
       (commands/ tree)  (your flags)   (io, cwd, env…)
              │               │               │
              └───────────────┴───────┬───────┘
                                      ▼
                              Your command's run()
                                      │
                                      ▼
                                  Exit code

Features

  • No Boilerplate No manual imports or routing logic, just create files in the /commands directory or define your own.
  • Typed Arguments Flags and positionals are declared once and arrive in the handler function already parsed, coerced, and typed.
  • Zero-Config Auto-discover commands from the filesystem, leaving you nothing to wire up by hand.
  • Lightweight No runtime dependencies: the framework is the only thing in your node modules.
  • Bun-Optimized Lean on Bun's speed and native TypeScript.
  • Compiles to Binary Ship your CLI as a single standalone executable with bun build --compile.

Getting Started

Requires Bun 1.3 or later.

mkdir new-cli && cd new-cli

bun init -y
bun add concise-ti

You only ever touch two kinds of files: the entrypoint, written once, and command files, dropped in as your CLI grows:

new-cli/
├── main.ts      ← written once, never touched again
└── commands/
    └── fib.ts   ← app fib

Create commands/fib.ts:

import { command } from 'concise-ti'

export default command({
  meta: { description: 'Compute a Fibonacci number, or the sequence leading to it' },
  flags: {
    sequence: { type: 'boolean', short: 's', description: 'Print the whole sequence up to n' },
  },
  run(ctx) {
    const n = Number(ctx.positionals[0] ?? 10),
      sequence = ctx.flags.sequence === true,
      values = [0, 1]

    for (let i = 2; i <= n; i++) values.push(values[i - 1] + values[i - 2])

    ctx.io.write(sequence ? values.slice(0, n + 1).join(', ') : String(values[n]))
  },
})

The flags block is enough to get a typed --sequence toggle in ctx.flags. No manual parsing, no wiring it into a parser yourself.

Create main.ts:

import { run } from 'concise-ti'

void run({ name: 'new-cli', version: '1.0.0' }, import.meta)

That's the whole entrypoint, and it's the last time you'll edit it. concise-ti automatically discovers commands from the commands directory, turns fib.ts into the fib route, parses argv against its declared flags, and dispatches automatically on every run. Add a second file and app second-command exists with no further wiring. See Command Routing for how the file structure maps to commands. Prefer to list commands by hand instead of relying on the filesystem? See Manifest for the inline defineManifest alternative.

Run it:

bun run ./main.ts fib 10
# Output: 55

bun run ./main.ts fib 10 --sequence
# Output: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55

Compile it to a standalone binary:

bunx concise-ti compile ./main.ts --outfile dist/my-cli
./dist/my-cli fib 10 --sequence

A CLI built entirely with defineManifest, no commands/ directory, can compile directly with bun build --compile; concise-ti compile is only needed to make filesystem-discovered commands work inside the compiled binary. See Manifest.

Documentation

The example above is just a taste. Full docs live in /docs; pick the one below based on what you're trying to do: