mrkeyoor.com_
Wed 05 Aug 23:10 UTC
npmCLI & Toolingupdated 05 Aug 2026

minimist

minimist is the minimal argv parser: one function that turns process.argv into an object of flags and positionals, with aliases, defaults, booleans, and '--' handling. It is 'the guts of optimist's argument parser without all the fanciful decoration', at 1.3KB gzipped with zero dependencies. Its 149M weekly downloads are almost entirely transitive, since half of older npm depends on it somewhere. After prototype-pollution incidents, stewardship moved to the minimistjs org; the current 1.2.8 dates from February 2023.

Verdict

For years the correct tiny argv parser, and it still works fine; but on any Node from the last few years, util.parseArgs does the same job built-in and stricter. Choose minimist today only for legacy runtimes or deliberate loose passthrough parsing; existing usage is not worth panicking over, on 1.2.8.

API stability5/5One function whose behavior has been frozen for a decade; 1.2.8 is three years old and nothing about the parsing contract has changed since the security fixes.
Docs3/5The README covers every option with examples in a few screens, which fits the scope, but edge-case behavior (numeric coercion, grouping, boolean consumption of true/false) is under-explained and mostly learned by surprise.
Maintenance3/5The minimistjs org keeps CI green (pushes through December 2025) and the security holes were fixed, but there has been no release since February 2023 and the package is in maintenance mode by design.
Ecosystem4/5149M weekly downloads and ubiquity in older dependency trees mean infinite examples and battle-testing, but the ecosystem is moving to util.parseArgs and typed alternatives for new code.

Use it if

  • You are writing a small script or internal tool and just need '--port 3000 --verbose' parsed into an object with zero ceremony
  • You cannot use Node's built-in util.parseArgs because you must support Node older than 18.3, and you still want something tiny
  • You need loose parsing on purpose: minimist accepts unknown flags without configuration, which suits passthrough wrappers around other CLIs
  • Install size actually matters: 1.3KB and zero dependencies versus tens of packages for yargs
Skip it if

Setup reality

npm install minimist, require or import the one function, done: CJS and works everywhere, no build questions. The care points are behavioral: numeric-looking values are auto-converted to numbers (version strings like 1.10 become 1.1 unless you list the flag in opts.string), single letters group ('-abc' is three booleans), and every unknown flag is accepted silently. Security history matters here too: two prototype-pollution advisories (fixed by 1.2.6) mean anything older in a lockfile still trips audits, so make sure resolution lands on 1.2.8.

Patterns

Parse process.argvbasic-parse

const minimist = require('minimist');

const argv = minimist(process.argv.slice(2));
// node app.js -x 3 --beep=boop foo bar
// { _: ['foo', 'bar'], x: 3, beep: 'boop' }

Always slice(2) to drop the node binary and script path. Positionals land in argv._; everything else becomes a key, whether you expected it or not.

Pin flags as strings or booleansdeclare-types

const argv = minimist(process.argv.slice(2), {
  string: ['version', 'port'],
  boolean: ['verbose', 'force'],
});
// --version 1.10 stays '1.10' instead of becoming 1.1

Without opts.string, numeric-looking values are converted: '1.10' becomes the number 1.1 and leading zeros vanish. Listing a flag in boolean also stops it swallowing the next argument.

Aliases and defaultsalias-default

const argv = minimist(process.argv.slice(2), {
  alias: { p: 'port', v: 'verbose' },
  default: { port: 3000, verbose: false },
});
// -p 8080  =>  argv.port === 8080 && argv.p === 8080

Aliases populate both keys in the output, so destructure the long name and ignore the short one. Defaults apply only when the flag is completely absent.

Negation with --no-negated-flags

const argv = minimist(['--no-color']);
// { _: [], color: false }

--no-foo yields foo: false automatically, no configuration needed. Combine with defaults ({ color: true }) to give users an off switch.

Pass arguments through after --double-dash-passthrough

const argv = minimist(process.argv.slice(2), { '--': true });
// node run.js --debug -- node child.js --port 3000
// argv._ = [], argv.debug = true
// argv['--'] = ['node', 'child.js', '--port', '3000']

With '--': true the tail is separated into argv['--'] instead of mixed into argv._, which is exactly what wrapper CLIs that spawn other commands need.

Subcommand-style parsing with stopEarlysubcommand-stop-early

const argv = minimist(process.argv.slice(2), { stopEarly: true });
const [command, ...rest] = argv._;

if (command === 'build') {
  const buildArgs = minimist(rest, { boolean: ['watch'] });
}

stopEarly puts everything after the first positional into argv._ unparsed, letting you re-parse per subcommand. This is as far as minimist scales; past two subcommands, switch to commander.

Reject unknown flagsreject-unknown

const known = ['port', 'verbose', 'p', 'v', '_'];
const argv = minimist(process.argv.slice(2), {
  alias: { p: 'port', v: 'verbose' },
  unknown: (arg) => {
    if (arg.startsWith('-')) {
      console.error(`unknown option: ${arg}`);
      process.exit(1);
    }
    return true; // keep positionals
  },
});

By default typos become new keys silently ('--prot 3000' just works, wrongly). The unknown callback is the only strictness mechanism minimist offers; returning false drops the arg.

Grouped short flags and attached valuesgrouped-short-flags

const argv = minimist(['-abc', '-n5']);
// { _: [], a: true, b: true, c: true, n: 5 }

'-abc' expands to three booleans and '-n5' attaches the value, matching Unix convention. This also means a mistyped '-port' parses as four separate booleans, not a flag named port.

Make sure resolution lands on 1.2.8audit-lockfile-version

npm ls minimist
# force old transitive copies up via package.json:
{
  "overrides": { "minimist": "^1.2.8" }
}

The prototype-pollution advisories were fixed by 1.2.6, but ancient transitive pins (0.x, 1.2.0) still lurk in old lockfiles and light up npm audit; an override settles it.

The zero-dependency modern alternativebuiltin-parseargs

import { parseArgs } from 'node:util';

const { values, positionals } = parseArgs({
  options: {
    port: { type: 'string', short: 'p', default: '3000' },
    verbose: { type: 'boolean', short: 'v' },
  },
  allowPositionals: true,
});

Stable since Node 18.3/20: declared types, unknown flags throw, no dependency. For new code on modern Node this replaces minimist outright; note values are strings, never auto-numbers.

Alternatives

PackageRegistryPick it when
commandernpmYou are building a real CLI with subcommands, help text, and validation and want the most conventional API.
yargsnpmYou want rich parsing plus middleware, completion, and locale features and can accept a much heavier dependency tree.
argnpmYou want minimist's size class but with explicit flag types declared up front instead of guessing.