minimist and nopt are both lightweight libraries for parsing command-line arguments in Node.js applications. They convert process.argv input into structured JavaScript objects, making it easier to handle user-provided flags and options. While both serve the same fundamental purpose, they differ significantly in parsing behavior, configuration capabilities, and design philosophy.
Both minimist and nopt solve the same core problem: turning raw command-line strings like --port 8080 --verbose into clean JavaScript objects your code can use. But they take very different approaches to parsing, validation, and usability. Let’s compare them in real-world scenarios.
minimist uses intuitive heuristics to infer types and group values.
-p 8080) and long flags (--port 8080) work out of the box.// minimist example
const minimist = require('minimist');
const args = minimist(['--port', '8080', '--verbose', '-f', 'input.txt']);
// Result: { _: [], port: 8080, verbose: true, f: 'input.txt' }
nopt requires explicit type definitions but enforces structure.
// nopt example
const nopt = require('nopt');
const knownOpts = { port: Number, verbose: Boolean, file: String };
const shortHands = { p: ['--port'], v: ['--verbose'], f: ['--file'] };
const args = nopt(knownOpts, shortHands, ['--port', '8080', '--verbose', '-f', 'input.txt']);
// Result: { port: 8080, verbose: true, file: 'input.txt', argv: { ... } }
minimist guesses types based on input format:
--count 5 → 5)--debug → true)// minimist type inference
const args = minimist(['--timeout', '1000', '--dry-run', '--name', 'test']);
// { timeout: 1000, 'dry-run': true, name: 'test' }
nopt requires you to define types explicitly:
// nopt strict typing
const opts = { timeout: Number, dryRun: Boolean, name: String };
const args = nopt(opts, {}, ['--timeout', '1000', '--dry-run', '--name', 'test']);
// { timeout: 1000, dryRun: true, name: 'test' }
minimist has no built-in support for default values. You handle defaults in your own code:
// minimist defaults (manual)
const argv = minimist(process.argv.slice(2));
const port = argv.port || 3000;
const host = argv.host || 'localhost';
nopt doesn't set defaults either, but its strict typing makes post-parse default assignment cleaner:
// nopt defaults (still manual, but typed)
const parsed = nopt({ port: Number }, {}, process.argv);
const config = {
port: parsed.port ?? 3000,
host: parsed.host ?? 'localhost'
};
Note: Neither library provides automatic default value injection — that’s typically handled by higher-level CLI frameworks like yargs or commander.
minimist never throws errors for unknown flags. Everything unrecognized goes into the _ array:
// minimist ignores unknowns
const args = minimist(['--unknown', 'value', 'file.txt']);
// { _: ['file.txt'], unknown: 'value' }
nopt discards unknown flags by default but can be configured to warn:
// nopt ignores unknowns silently
const args = nopt({ known: String }, {}, ['--unknown', 'flag']);
// { known: undefined } (no 'unknown' property)
Neither provides built-in validation error messages — you’d need to layer that on top.
You’re writing a build script that accepts --watch, --output dir, and source files.
minimist_ for file handling.const args = minimist(process.argv.slice(2));
const { watch, output = 'dist' } = args;
const files = args._; // ['src/index.js', 'src/utils.js']
You’re building a CLI that must reject invalid inputs and enforce types (e.g., --retries must be a number ≥ 0).
noptconst parsed = nopt({ retries: Number }, {}, process.argv);
if (typeof parsed.retries !== 'number' || parsed.retries < 0) {
throw new Error('--retries must be a non-negative number');
}
Both packages are mature and stable:
minimist is actively maintained with security patches as needed.nopt is maintained by the npm team and used internally by npm itself.Neither is deprecated, and both remain excellent choices for low-level argument parsing without heavy dependencies.
| Feature | minimist | nopt |
|---|---|---|
| Type Handling | Automatic inference | Explicit declaration required |
| Configuration | Zero config for basic use | Requires type definitions |
| Unknown Flags | Preserved in _ array | Silently discarded |
| Default Values | Not supported (handle manually) | Not supported (handle manually) |
| Error Prevention | Permissive (may hide typos) | Strict (catches invalid types early) |
| Best For | Simple scripts, quick prototypes | Robust CLIs, type-safe interfaces |
Use minimist when you want "just parse these args" with minimal ceremony. It’s the go-to for small utilities and internal tools where flexibility matters more than strict contracts.
Use nopt when you’re building a public-facing CLI that needs to enforce option types and avoid ambiguous interpretations. Its explicit typing prevents subtle bugs in complex argument scenarios.
For most modern projects, consider whether you actually need these low-level parsers — higher-level tools like yargs or commander often provide better DX with built-in help, validation, and subcommands. But when you do need a lean, focused parser, both minimist and nopt deliver reliable, battle-tested solutions.
Choose minimist if you need a minimal, zero-dependency parser that handles basic short and long flag syntax with automatic type inference. It's ideal for simple CLIs where you want predictable parsing without complex validation or configuration overhead.
Choose nopt if you require strict type validation, support for default values, and more control over how arguments are interpreted. It's well-suited for larger CLI tools that need robust error handling and consistent option typing, especially when building npm-compatible interfaces.
parse argument options
This module is the guts of optimist's argument parser without all the fanciful decoration.
var argv = require('minimist')(process.argv.slice(2));
console.log(argv);
$ node example/parse.js -a beep -b boop
{ _: [], a: 'beep', b: 'boop' }
$ node example/parse.js -x 3 -y 4 -n5 -abc --beep=boop foo bar baz
{
_: ['foo', 'bar', 'baz'],
x: 3,
y: 4,
n: 5,
a: true,
b: true,
c: true,
beep: 'boop'
}
Previous versions had a prototype pollution bug that could cause privilege escalation in some circumstances when handling untrusted user input.
Please use version 1.2.6 or later:
var parseArgs = require('minimist')
Return an argument object argv populated with the array arguments from args.
argv._ contains all the arguments that didn't have an option associated with
them.
Numeric-looking arguments will be returned as numbers unless opts.string or
opts.boolean is set for that argument name.
Any arguments after '--' will not be parsed and will end up in argv._.
options can be:
opts.string - a string or array of strings argument names to always treat as
strings
opts.boolean - a boolean, string or array of strings to always treat as
booleans. if true will treat all double hyphenated arguments without equal signs
as boolean (e.g. affects --foo, not -f or --foo=bar)
opts.alias - an object mapping string names to strings or arrays of string
argument names to use as aliases
opts.default - an object mapping string argument names to default values
opts.stopEarly - when true, populate argv._ with everything after the
first non-option
opts['--'] - when true, populate argv._ with everything before the --
and argv['--'] with everything after the --. Here's an example:
> require('./')('one two three -- four five --six'.split(' '), { '--': true })
{
_: ['one', 'two', 'three'],
'--': ['four', 'five', '--six']
}
Note that with opts['--'] set, parsing for arguments still stops after the
--.
opts.unknown - a function which is invoked with a command line parameter not
defined in the opts configuration object. If the function returns false, the
unknown option is not added to argv.
With npm do:
npm install minimist
MIT