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

riker

v1.4.3

Published

Riker is an opinionated tool for building CLI interfaces in node.js.

Downloads

25

Readme

Riker

Riker is an opinionated node.js cli library for handling the business of writing that makes it optimizes for composability, testability, and unixy best practices. It is is designed to allow authors to create fluent interfaces with subcommands that are all classes where the commands themselves are unit testable.

Beliefs

  1. All code should be easily testable and tested, even command line scripts.
  2. Dependency injection is a Good Idea™.
  3. Configuration should be injecteable inheritable.
  4. Configuration should be specifiable in configuration files, environment variables, and command like arguments. In that order.
  5. Streams are the one true Node.js abstraction
  6. Composable

But why is it called "Riker"?

Because the only thing that should ever come after "commander" is "Riker".

William T. Riker

Architecture

  • Riker
    • Main entry point
    • Provides helpers for things like loading a directory of commands
  • CommandCollection
    • Is a collection of subcommands
    • Resolves command aliases and loads child commands
    • Child commands can, themselves, be command collections
  • Command
    • Is an individual command

Usage

Creating a custom command.

const Riker = require('riker');
const Command = Riker.Command;

class Cat extends Command {
  constructor() {
    super();
    this.shortDescription = 'Sends any input to standard out';
    this.help = 'This command streams input coming to standard in and pipes it to standard out.';
  }
  configure(options) {
    this.someOption = options.someOption;
  }
  run(done) {
    this.input.pipe(this.output);
    if (done) {
      this.input.on('end', done);
    }
  }
}

Creating a custom command with config parameters.

const Riker = require('riker');
const Command = Riker.Command;

class Cat extends Command {
  constructor() {
    super();
    this.shortDescription = '';
    this.help = 'Help placeholder';
    const parameter = this.addParameter('server.port');
    parameter
      .type(Number) // Defines the type - this will cast the type if necessary to ensure numbers, strings, etc are handled appropriately.
      // Mappings
      .default(80) // Provides a default value for this parameter.
      .required() // Marks this parameter required, incompatible with `default`.
      .describe('Specify the port.') // Provide help text related to this option, wrapped behavior from yargs.
      .alias('p') // An alias for this command, wrapped behavior from yargs.
    this.addParameter('protocol')
      .alias('P')
      .describe('Whether to listen use TLS.')
      .default('http')
      .choices(['http', 'https']) // Provide a set of allowable options.
  }
  configure(options) {
    this.someOption = options.someOption;
  }
  run(done) {
    this.input.pipe(this.output);
    if (done) {
      this.input.on('end', done);
    }
  }
}

Writing a unit test

Unit testing our class by mocking input using through2 and should.

describe('Cat', function() {
  it('should stream anything input to the output', function() {
    const Cat = require('./Cat');
    const through2 = require('through2');
    const should = require('should');
    const history = [];
    const input = through2();
    const output = through2(function(data, enc, cb) {
      history.push(data);
      cb(data);
    })
    const cat = new Cat({input, output})
    output.on('end', function() {
      history.length.should.equal(2);
      history[0].should.equal('one');
      history[1].should.equal('two');
      done()l
    });
    input.write('one');
    input.write('two');
    input.write(null);
  });
}

Creating a set of subcommands in a command collection

var Riker = require('riker');
var Cat = require('./Cat');
var Command = Riker.Command;

var command = new Command();

var riker = new Riker();
riker.addSubCommand('bar', new Foo());
var baz = new Command();
baz.shortDescription = 'This is baz.';
baz.help = 'Baz knows about stuff…';
baz.addSubCommand('bingo', new Foo());
riker.addSubCommand('baz', baz);
riker.addSubCommand('help', new Riker.commands.Help());
riker.run(function() {
  //console.log('command line run done');
});