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

@munesoft/flagx

v1.10.20

Published

Tiny CLI flag utility with superpowers. A has-flag alternative for Node.js with zero dependencies.

Readme

@munesoft/flagx

Tiny CLI flag utility with superpowers. A has-flag alternative that actually grows with your needs.

npm version zero dependencies size license


What is flagx?

flagx is a modern Node.js argv parser — a cli flag parser and has-flag alternative — designed to be the last flag utility you'll ever need. It's tiny, fast, and zero-dependency, but covers everything from simple boolean checks to advanced grouped flags, aliasing, type inference, and validation.

Most tools are either too simple (has-flag — booleans only) or too heavy (minimist, yargs — full parsers with baggage). flagx sits in the middle: a tiny utility that punches way above its weight class.

Simple boolean check?       → One line.
Need a port number?         → One line.
DB config group?            → One line.
Light validation?           → One line.

Why flagx?

| Feature | has-flag | minimist | flagx | |---|---|---|---| | Boolean flags | ✅ | ✅ | ✅ | | Value extraction | ❌ | ✅ | ✅ | | Type inference | ❌ | ✅ | ✅ | | Aliases | ❌ | ✅ | ✅ | | Glob pattern matching | ❌ | ❌ | ✅ | | Flag grouping | ❌ | ❌ | ✅ | | Merge env/config | ❌ | ❌ | ✅ | | Lazy + cached parse | ❌ | ❌ | ✅ | | Light validation | ❌ | ❌ | ✅ | | Zero dependencies | ✅ | ✅ | ✅ | | Bundle size | ~0.1KB | ~3KB | <2KB |


Quick Start

npm install @munesoft/flagx
import flagx from "@munesoft/flagx";

// That's it. One line.
if (flagx("debug")) {
  console.log("debug mode on");
}

Works with all standard flag styles out of the box:

node app.js --debug --port=3000 --no-verbose -f -abc

Examples

Boolean check (the has-flag replacement)

import flagx from "@munesoft/flagx";

flagx("debug");     // true/false
flagx("verbose");   // true/false
flagx("prod");      // true/false

Get a value with default

const port = flagx.value("port", 3000);
const host = flagx.value("host", "localhost");

Transform on read

const port = flagx.value("port", Number);         // → always a number
const tags = flagx.value("tag", v => v.split(",")); // → array from string

Aliases

flagx.alias({ p: "port", v: "verbose", h: "host" });

// Now -p 3000 and --port=3000 both work
const port = flagx.value("port");

Pick multiple flags at once

const { port, host, debug } = flagx.pick(["port", "host", "debug"]);

Multi-flag logic

flagx.hasAny(["debug", "verbose"]);    // at least one
flagx.hasAll(["port", "host"]);        // all required

Glob pattern matching

// Flag: --db.host=localhost --db.port=5432 --db.ssl=true
const dbFlags = flagx.match("db.*");
// → { "db.host": "localhost", "db.port": 5432, "db.ssl": true }

Grouping

// Flag: --db.host=localhost --db.port=5432
const db = flagx.group("db");
// → { host: "localhost", port: 5432 }

// Perfect for connecting to a database:
const client = new DB(db);

Merge env vars or config

flagx.merge({
  env: process.env,
  config: { port: 3000, host: "localhost" },
});

// CLI flags always win. Env and config fill in gaps.
const port = flagx.value("port"); // from CLI, env, or config

Light validation

flagx.expect({
  port: "number",
  debug: "boolean",
  name: "string",
});
// Warns on type mismatch, throws in strict mode

Strict mode

const fx = flagx({ strict: true });
fx.expect({ port: "number" }); // throws if wrong type

Command detection

// $ node cli.js build --watch
const cmd = flagx.command(); // → "build"

Flag metadata

const meta = flagx.meta("port");
// → { exists: true, value: 3000, index: 0, raw: "--port=3000" }

Debug output (dev tool)

flagx.debug();
// [flagx debug] Parsed flags:
//   --port                 3000                 (number)
//   --debug                true                 (boolean)

JSON output (AI-friendly)

console.log(flagx.json());
// { "port": 3000, "debug": true }

API Reference

flagx(name): boolean

Check whether a flag is present and truthy. The core has-flag-style API.

flagx("debug"); // true/false

flagx(options): api

Configure the instance. Currently supports { strict: boolean }.

flagx({ strict: true });

flagx.value(name, defaultOrTransform?): any

Get a flag's value. Pass a default value or a transform function as the second argument.

flagx.value("port");              // raw value or undefined
flagx.value("port", 3000);        // with default
flagx.value("port", Number);      // transform: coerce to number
flagx.value("host", v => `http://${v}`); // arbitrary transform

flagx.pick(keys[]): object

Extract multiple flags at once.

flagx.pick(["port", "host", "debug"]);
// → { port: 3000, host: "localhost", debug: true }

flagx.all(): object

Return all parsed flags as a plain object.

flagx.all(); // → { port: 3000, debug: true, ... }

flagx.hasAny(keys[]): boolean

Returns true if at least one of the keys is present and truthy.


flagx.hasAll(keys[]): boolean

Returns true only if all keys are present and truthy.


flagx.match(pattern): object

Return all flags matching a glob-style pattern (* wildcard).

flagx.match("db.*");     // → all --db.x flags
flagx.match("--no-*");   // → all negated flags

flagx.group(prefix): object

Return all flags under a prefix, with the prefix stripped from keys.

// --db.host=localhost --db.port=5432
flagx.group("db"); // → { host: "localhost", port: 5432 }

flagx.meta(name): object

Return metadata about a flag.

flagx.meta("port");
// → { exists: true, value: 3000, index: 0, raw: "--port=3000" }

flagx.alias(map): api

Register short-to-long aliases. Chainable.

flagx.alias({ p: "port", v: "verbose" });

flagx.merge(sources): api

Merge additional flag sources. CLI args always take precedence.

flagx.merge({ env: process.env, config: loadConfig() });

flagx.expect(schema): boolean

Validate flag types. Warns by default; throws in strict mode.

flagx.expect({ port: "number", debug: "boolean" });

Supported types: "boolean", "number", "string", "array"


flagx.command(): string | undefined

Returns the first positional argument (typically a subcommand).


flagx.positionals(): string[]

Returns all non-flag positional arguments.


flagx.raw(): string[]

Returns the raw argv slice (everything after node script.js).


flagx.debug(): api

Prints all parsed flags with types to stdout. Dev-only tool.


flagx.json(): string

Returns all flags as a formatted JSON string.


flagx.from(argv[]): api

Override the argv source. Useful for testing.

flagx.from(["--port=3000", "--debug"]);

flagx.reset(): api

Reset all state including aliases, merges, and cache.


Parsing Rules

flagx supports every common CLI flag syntax:

| Input | Result | |---|---| | --flag | true | | --flag=true | true (boolean) | | --flag=false | false (boolean) | | --no-flag | false | | --key=value | "value" (string) | | --port=3000 | 3000 (number) | | -f | true | | -abc | a=true, b=true, c=true | | -p 3000 | p=3000 | | --flag --flag | [true, true] (array) | | -- | stop parsing (rest → positionals) |

Note on space-separated values: For long flags (--key value), flagx only greedily consumes the next token when it's a typed value (number or boolean). For string values, use --key=value syntax. Short flags (-p value) always consume the next token.


Performance

flagx is built around two core principles:

Lazy parsing — argv is never touched until the first API call.

Single parse — the result is cached after the first call. Every subsequent call — flagx("x"), flagx.value("y"), flagx.all() — uses the same cached object.

100 × 1000-flag parses:   ~38ms
Cached access:            ~0ms

This makes flagx safe to call anywhere — top of a file, in hot paths, conditionally — with no performance penalty.


Comparison

vs has-flag

has-flag does one thing: checks if a flag string exists in process.argv. No values, no types, no aliases. flagx replaces it with a superset that's still a one-liner.

vs minimist

minimist is a capable parser but is heavier (~3KB), older, and doesn't offer grouping, pattern matching, lazy parsing, merge sources, or built-in validation. flagx weighs less and does more.

vs yargs/commander

These are full CLI frameworks: help generation, command routing, middleware. If you're building a complex CLI application, they're worth it. If you just need to read flags in a script, a library, or a build tool, flagx is the right weight.


FAQ

Does flagx work in CommonJS? Currently ESM-only (type: "module"). A CJS build can be added if needed.

Does it handle process.argv automatically? Yes. By default it reads process.argv.slice(2). Use flagx.from([...]) to override.

Can I use it in a library (not a CLI)? Yes. Use flagx.from(argv) with a passed-in array rather than process.argv.

Is the parse result mutable? flagx.all() returns a shallow copy. The internal cache is not exposed directly.

What about Windows-style /flag syntax? Not supported — flagx follows the POSIX/GNU convention used by Node.js ecosystem tools.


Keywords

cli flag parser · nodejs argv parser · command line flags javascript · has-flag alternative · minimist alternative · argv · cli · flags · parse · args


License

MIT © Munesoft