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

@keeex/argv

v1.1.1

Published

Parses argv arguments

Readme

CLI argv parser

Design goal

This library handles parsing arguments from the CLI, and putting them in a JavaScript object. It optionally provides some amount of type safety for TypeScript usage.

It handles basic single-characters and multi-characters options, options arguments, and unnamed arguments. It also support one level of "selector", making it possible to toggle between different set of parsing options.

It does not support positional arguments, and options ordering isn't enforced.

Some default options are handled automatically, such as displaying inline help, versions, or licensing informations.

Usage

An object which describe all the available options must be provided.

Global configuration

It's interface is:

export interface ArgvOptions<ArgvConfig = unknown> {
  /** Don't stop if there are extra, unhandled arguments */
  allowExtraArgs?: boolean;
  /** Defaults to `path.basename(process.argv[1])` */
  appName?: string;
  /** Provide top-level branching options. */
  branches?: ArgvOptionBranch;
  description?: string;
  /**
   * Extra, unnamed arguments.
   *
   * Can be overriden by branch options.
   */
  extraArgs?: ExtraArgs;
  /** Full license terms */
  license?: string;
  /** Short license terms */
  licenseShort?: string;
  /** Available options (shared by all branches, if any) */
  options?: Array<ArgvOption>;
  /** Defaults to `console.info()` output */
  outputFunction?: (value: string) => void;
  /** Type predicate applied to the final object before returning it. */
  predicate?: TypePredicate<ArgvConfig>;
  /** Displayed as a header for all inline help */
  title?: string;
  /** Version (without "v" prefix) */
  version?: string;
}

The options are described using one of these interfaces:

export interface ArgvOptionBase<Type> {
  /**
   * How to cast the raw value to the config property value.
   *
   * If not provided, will use the raw value.
   */
  cast?: (value: Type) => Awaitable<unknown>;
  default?: Type;
  description?: string;
  mandatory?: boolean;
  /** no prefix dash */
  short?: string;
  /** kebab-case, no prefix dashes */
  long?: string;
  /**
   * Property in the result object.
   *
   * Defaults to the camelcase version of the long form if present, or the short form.
   * Only handle top-level, no object properties.
   */
  propertyName?: string;
}

/** Accept a single boolean value */
export interface ArgvOptionBoolean extends ArgvOptionBase<boolean> {
  type: "boolean";
}

/** Accept multiple boolean values */
export interface ArgvOptionBooleanArray extends ArgvOptionBase<Array<boolean>> {
  type: "booleanArray";
}

interface ArgvOptionBranchOptions {
  extraArgs?: ExtraArgs | null;
  options?: Array<ArgvOption>;
}

/** Accept a single choice argument */
export interface ArgvOptionChoice extends ArgvOptionBase<string> {
  choices: Array<string>;
  type: "choice";
}

/** Accept multiple choice arguments */
export interface ArgvOptionChoiceArray extends ArgvOptionBase<Array<string>> {
  choices: Array<string>;
  type: "choiceArray";
}

/** Accept a single number argument */
export interface ArgvOptionNumber extends ArgvOptionBase<number> {
  /** Name of the argument. Defaults to `value`. */
  argName?: string;
  type: "number";
}

/** Accept multiple number arguments */
export interface ArgvOptionNumberArray extends ArgvOptionBase<Array<number>> {
  /** Name of the argument. Defaults to `value`. */
  argName?: string;
  type: "numberArray";
}

/** Accept a single string argument */
export interface ArgvOptionString extends ArgvOptionBase<string> {
  /** Name of the argument. Defaults to `value`. */
  argName?: string;
  type: "string";
}

/** Accept multiple string arguments */
export interface ArgvOptionStringArray extends ArgvOptionBase<Array<string>> {
  /** Name of the argument. Defaults to `value`. */
  argName?: string;
  type: "stringArray";
}

Each option will return the expected type by default. That value can be altered before it is returned by defining a cast property.

Branching option

In addition to shared options, it is possible to define a "branching" option which takes a string and will process all options according to a different configuration object. This can be set in the branches property of the top-level config object.

export interface ArgvOptionBranch extends ArgvOptionBase<string> {
  cast?: never;
  /** What is the branch option. Defaults to "Branches options". */
  name?: string;
  options: Record<string, ArgvOptionBranchOptions>;
  type: "branch";
}

interface ArgvOptionBranchOptions {
  extraArgs?: ExtraArgs | null;
  options?: Array<ArgvOption>;
}

If present, options in this object's options[<value>] will be parsed in addition to the shared ones.

Unnamed arguments

It is possible to provide extra text values after all options are processed. These are queued at the end of the CLI call, and should not start with a -. If an unnamed argument must start with a -, it must be placed after the delimiter --, which indicates that everything after it is an unnamed argument.

It is possible to specify how many of these arguments are expected by configuring the extraArgs property:

export interface ExtraArgs {
  /** Name of the extra arguments, for the inline help */
  argName?: string;
  cast?: (value: string) => Awaitable<unknown>;
  description?: string;
  max?: number;
  min?: number;
  /** Defaults to `extraArgs` */
  propertyName?: string;
}

The propertyName is the name of the property that will receive the array of string in the returned object.

This value can be overriden by branches.

Parsing argv

Argv arguments are processed using a single function call:

import {getArgvConfig} from "@keeex/argv";

interface ArgvConfig {
  name: string;
  port: number;
}

const isArgvConfig = (obj: unknown): obj is ArgvConfig => {
  if (!obj) return false;
  if (typeof obj.name !== "string") return false;
  if (typeof obj.port !== "number") return false;
  return true;
};

const cliConfig = await getArgvConfig(process.argv, {
  options: [
    {
      long: "name",
      mandatory: true,
      short: "n",
      type: "string",
    },
    {
      default: 3000,
      long: "port",
      short: "p",
      type: "number",
    },
  ],
  predicate: isArgvConfig,
});

if (cliConfig) {
  // Do something with it
}

Low-level usage

If you don't care much about the extra tooling but just want to grab a handful of options from the CLI, you can use the consumeArgv() function instead.

import * as argv from "@keeex/argv";

const input = consumeArgv(process.argv, ["i", "input"], true);
const verbose = consumeArgv(process.argv, ["v", "verbose"], false);
const files = argv.consumeArgvArgs(process.argv);

It handles both single-character options prefixed with one dash (-) and longer options prefixed with two dashes (--). If false is passed as the third parameter, it returns either true (if the flag was present), false (if the --no-<long form> flag was present), or undefined. If true is passed as the third parameter, an extra string is expected after the options, and if present, that string is returned.

In addition, this function handles two types of values for argv: if the first value of the argv array seems to be a node binary, it expects the real arguments to start at argv[2]. If that's not the case, it starts parsing arguments at argv[0].