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

clhoe

v1.1.2

Published

Provides simple, yet powerful, routing for command line interfaces.

Downloads

16

Readme

clhoe

This is an npm module that provides simple, yet powerful, routing for command line interfaces, in a similar fashion to mainstream HTTP routing.

Installation

$ npm install clhoe

Usage

In order to do antyhing with Clhoe, we first need to include her. Yes, the name is one heck of a pun on the actual name.

const Clhoe = require('clhoe')

Basic Routing

Routing is done by calling the route function on Clhoe. The defined routes will be executed automatically once all routes have been added.

Clhoe.route((command) => {
	// TODO: add routes
})

Inside the closure passed to route, we get the opportunity to define command routes. The command parameter passed to the closure we provided, is a function that when called, creates a new route: it takes the form command(path, callback), whereas the callback will be executed if the path matches with what is entered into the terminal.

Command Route Syntax

For an example, let us create a command that creates a new project:

command('new project', () => {
	console.log('Creating a new project...')
})

The callback will be called, if an only if, the passed arguments from the terminal are in the following order:

$ mycommand new project
Creating a new project...

Otherwise, nothing will be matched. How to add default behavior if no route was matched will be discussed once all the syntax has been covered.

Variable Captures

The above example is quite dull on its own. At the very least, it would be nice if the user could specify the name they want for their project:

command('new [project]', ({ project }) => {
	console.log('Creating a new project ' + project + '...')
})

The [] enclosed area captures whatever is typed in by the user and stores that in a variable, which we are able to extract from an object passed along to the callback provided to the command.

If the following is executed:

$ mycommand new monkeys
Creating a new project monkeys...

You can see we also specified a name for that project.

Optional Groups

Let us elaborate upon what we have and take it even further. For instance, let us say we wanted to have a means of specifying the type of the project, but we want it to be optional.

This can be accomplished by introducing an optional group, for which we can use the {} syntax:

command('new [project] {--type [type]}', ({ project, type }) => {
	type = type || 'default'
	
	if (!['default', 'amazing'].includes(type))
		throw new Error('Invalid type!')
	
	console.log('Creating a new ' + type + ' project ' + project + '...')
})

The type property on the variables object will be undefined if the user did not enter it, as such we are making sure it is given a default value.

$ mycommand new monkeys --type amazing
Creating a new amazing project monkeys...

Verbose Flag

Using what we know, let us implement an optional flag -v for the same program that will print additional information regarding the process of setting our project up.

command('new [project] {--type [type]} {-v}', ({ project, type }, groups) => {
	type = type || 'default'
	
	if (!['default', 'amazing'].includes(type))
		throw new Error('Invalid type!')
	
	console.log('Creating a new ' + type + ' project ' + project + '...')
	
	if (groups.includes('-v'))
	{
		// TODO: implement verbose mode
	}
})

We can check if an optional group was used by seeing if its name is available in the groups array added to the callback. If -v is included, we wish to create our example application in verbose mode.

Variable Captures Varargs

It is also possible to capture a varargs number of strings from the command the user typed in:

command('new [project] [...args]', ({ project, args }) => {
	console.log('Creating project ' + project + ' with:')
	
	for (let arg of args)
		console.log(arg)
})

The args we extracted will always be in the form of an array, as such on running the command, we might get something like this:

$ mycommand new monkeys lots of strings
Creating project monkeys with:
lots
of
strings

It is possible to use optional groups at the same time as using varargs, as optional groups are always evaluated first, before anything else is evaluated.

Default Command

If no route was matched, a default callback (if provided) will be called:

Clhoe.route((command) => {
	// ...
}).else(() => {
	console.log('No command was matched!')
})

The chained else function will add such a callback.

Help Command

Let us have a look at how a help command might be implemented:

let help = () => {
	console.log('Help command!')
}

Clhoe.route((command) => {
	// Full match: 'help'
	command('help', help)
	
	// ...
}).else(help)

Thus, either if $ mycommand help is successfully matched, or no match at all occurred, the help closure will be called:

$ mycommand help
Help command!

$ mycommand i will not match a route
Help command!

License

This module, and the code therein, is licensed under ISC.