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

json-parse-argv

v1.0.0

Published

A lightning-fast, single-pass command line argument parser with structure validation

Readme

🚀 json-parse-argv

A lightning-fast, single-pass command line argument parser with structural validation and elegant JSON configuration.

✨ Features

  • Concise JSON Configuration: Define your entire command structure in a single JSON object
  • Single-Pass Processing: Parses, validates, and populates all in one efficient scan
  • Type Safety: Built-in structure and type validation during parsing
  • Error Resilience: Configurable error handling with continue/abort control
  • Seamless Subcommand Support: First-class "exit" mechanism for complex command structures
  • Zero Dependencies: Pure JavaScript with no external libraries
  • Predictable Results: No type errors or undefined values (all variables are initialized)

📦 Installation

npm install json-parse-argv

🔍 Elegant Usage Example

import parse from 'json-parse-argv';

// Define your application's command structure
const gitReq = {
  // Global options
  help: {
    def: false,
    set: ['-h', '--help']
  },
  verbose: {
    def: false,
    set: ['-v', '--verbose']
  },
  // Subcommands (direct string array format for exit options)
  command: ['clone', 'push', 'pull', 'commit', 'checkout']
};

// Commit subcommand config
const commitReq = {
  message: {
    def: '',
    set: ['-m', '--message']
  },
  all: {
    def: false,
    set: ['-a', '--all']
  },
  amend: {
    def: false,
    set: ['--amend']
  }
};

function main() {
  const gitRes = {};
  
  // First parse to handle global options and identify subcommand
  const ret = parse(process.argv, 2, gitReq, gitRes, console.error);
  
  // Handle help flag
  if (gitRes.help) {
    showHelp();
    return;
  }
  
  // Check if a subcommand was encountered (returns object with next position)
  if (ret) {
    // ret contains { i, key, opt }:
    // - ret.i is the argv index to continue parsing from
    // - ret.key is the variable name in gitReq that triggered the exit ('command')
    // - ret.opt is the option string that triggered the exit (subcommand name)
    
    console.log(`Executing ${ret.opt} command...`);
    
    switch (ret.opt) {
      case 'commit':
        // Parse commit-specific options starting from ret.i
        const commitRes = {};
        parse(process.argv, ret.i, commitReq, commitRes, console.error);
        
        // Use the results
        console.log(
          `Committing with message: ${commitRes.message}`,
          commitRes.all ? '(all files)' : '',
          commitRes.amend ? '(amending)' : ''
        );
        break;
        
      case 'push':
        // Handle push command...
        break;
        
      // Handle other commands...
    }
  }
}

🛠️ API

parse(argv, i, req, res, err)
  • argv: Array of command line arguments (usually process.argv)
  • i: Starting index for parsing (usually 2)
  • req: Configuration object defining your command structure
  • res: Object that will be populated with parsed results
  • err: Error handler function, receives {msg, i, opt, key, val} and returns boolean

Return Value

The function returns either:

  • null
  • An object { i, key, opt } when exiting early due to an exit option, where:
    • i: The next index to resume parsing from
    • key: The variable name in the req object that triggered the exit
    • opt: The option string that triggered the exit (e.g., the subcommand name)

Configuration Format

{
  // Regular variable with default value and option definitions
  variableName: {
    def: defaultValue,     // Boolean, string, or string[]
    set: optionDefinition, // Options that set this variable
    rst: optionDefinition  // Options that reset this variable to default
  },
  
  // Exit option (shorthand format) - exits parsing when encountered
  exitOptionName: optionDefinition
}

Option definitions can be:

  • A string: '--option'
  • An array: ['--option', '-o']
  • null refers to the variable name. [null, ...] is also supported.

⚡ Powerful Features

Boolean Options

// Simple flags (no value needed)
verbose: {
  def: false,
  set: ['-v', '--verbose']
}

String Options

// String option with default value
output: {
  def: 'stdout',
  set: ['-o', '--output']
}

Array Collection

// Collect multiple values in an array
files: {
  def: [],
  set: ['-i', '--input'] // -i 1.txt --input 2.txt -i3.txt --input=4.txt
}

// Special option '--' collects all the anonymous arguments. 
allFiles: {
  def: [],
  set: ['--', '-i'] // -i 1.txt 2.txt -- --this-will-be-collected-too
}

Reset Options

// Option to reset value back to default
// For boolean values:
color: {
  def: false,
  set: ['--color'],   // Sets to true (!def)
  rst: ['--no-color'] // Resets to false (def)
}

big: {
  def: true,
  set: ['--small'], // Sets to false (!def)
  rst: ['--big']    // Resets to true (def)
}

// For strings or arrays, reset restores the original default:
files: {
  def: ['default.txt'],
  set: ['--files'],    // Adds files to array
  rst: ['--no-files']  // Resets back to ['default.txt']
}

Note: Inverting a boolean value is not supported.

Combined Short Options

const res = {};
parse(['node', 'app.js', '-abc'], 2, {
  a: { def: false, set: '-a' },
  b: { def: false, set: '-b' },
  c: { def: false, set: '-c' }
}, res, console.error);
// res = { a: true, b: true, c: true }
const res = {};
parse(['node', 'app.js', '-abcd'], 2, {
  a: { def: false, set: '-a' },
  b: { def: [], set: '-b' },
  c: { def: false, set: '-c' },
  d: { def: false, set: '-d' }
}, res, console.error);
// { a: true, b: [ 'cd' ], c: false, d: false }

🔄 Subcommand Handling

The exit feature enables elegant subcommand handling:

// Main CLI configuration
const mainReq = {
  help: {
    def: false,
    set: ['-h', '--help']
  },
  // Direct array format for exit options
  command: ['build', 'serve', 'test']
};

const mainRes = {};
const ret = parse(process.argv, 2, mainReq, mainRes, console.error);

if (ret) {
  // When a command is found via the exit mechanism:
  // - ret.i is already positioned after the subcommand
  // - ret.key contains the variable name in req ('command' in this case)
  // - ret.opt contains the matched option (the subcommand name)
  
  switch(ret.opt) {
    case 'build':
      const buildReq = { /* build options */ };
      const buildRes = {};
      parse(process.argv, ret.i, buildReq, buildRes, console.error);
      break;
  }
}

📜 License

MIT © Chinory