CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-meow

CLI app helper that simplifies building command-line interfaces in Node.js with automatic argument parsing and flag handling

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

Meow

Meow is a CLI app helper that simplifies building command-line interfaces in Node.js. It automatically parses command-line arguments and flags, converts flags to camelCase format, provides built-in support for version and help text output, handles flag negation with --no- prefix, and includes advanced features like flag validation, multiple value support, and required flag detection.

Package Information

  • Package Name: meow
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install meow

Core Imports

import meow from 'meow';

Import with types for TypeScript:

import meow, { type Options, type Result, type FlagType } from 'meow';

For CommonJS:

const meow = require('meow');

Basic Usage

#!/usr/bin/env node
import meow from 'meow';

const cli = meow(`
  Usage
    $ foo <input>

  Options
    --rainbow, -r  Include a rainbow

  Examples
    $ foo unicorns --rainbow
    🌈 unicorns 🌈
`, {
  importMeta: import.meta,
  flags: {
    rainbow: {
      type: 'boolean',
      shortFlag: 'r'
    }
  }
});

/*
{
  input: ['unicorns'],
  flags: {rainbow: true},
  unnormalizedFlags: {rainbow: true, r: true},
  pkg: {...},
  help: '...',
  showHelp: [Function],
  showVersion: [Function]
}
*/

console.log('Input:', cli.input);
console.log('Flags:', cli.flags);

Capabilities

CLI Parsing

Main function that processes command-line arguments and returns a parsed result object.

/**
 * Parse command-line arguments with help text and options
 * @param helpMessage - Help text to display with --help
 * @param options - Configuration options for parsing
 * @returns Parsed CLI result object
 */
function meow<Flags extends AnyFlags>(
  helpMessage: string, 
  options?: Options<Flags>
): Result<Flags>;

/**
 * Parse command-line arguments with options only
 * @param options - Configuration options for parsing
 * @returns Parsed CLI result object
 */
function meow<Flags extends AnyFlags>(options?: Options<Flags>): Result<Flags>;

Flag Definition

Configure argument flags with various options and validation rules.

interface Flag<PrimitiveType extends FlagType, Type, IsMultiple = false> {
  /** Type of value: 'string' | 'boolean' | 'number' */
  readonly type?: PrimitiveType;
  /** Limit valid values to predefined choices */
  readonly choices?: Type extends unknown[] ? Type : Type[];
  /** Default value when flag is not specified */
  readonly default?: Type;
  /** Single character alias for the flag */
  readonly shortFlag?: string;
  /** Alternative names for the flag */
  readonly aliases?: string[];
  /** Allow multiple values (creates array) */
  readonly isMultiple?: IsMultiple;
  /** Determine if flag is required (boolean or function) */
  readonly isRequired?: boolean | IsRequiredPredicate;
}

Flag Usage Examples:

// String flag with choices and aliases
flags: {
  unicorn: {
    type: 'string',
    choices: ['rainbow', 'cat', 'unicorn'],
    default: 'rainbow',
    shortFlag: 'u',
    aliases: ['unicorns']
  }
}

// Multiple boolean flag
flags: {
  verbose: {
    type: 'boolean',
    isMultiple: true,
    shortFlag: 'v'
  }
}

// Required flag with dynamic requirement
flags: {
  output: {
    type: 'string',
    isRequired: (flags, input) => {
      return flags.format === 'file';
    }
  }
}

Configuration Options

Configure parsing behavior, help text, and validation rules.

interface Options<Flags extends AnyFlags> {
  /** Required import.meta object for package.json discovery */
  readonly importMeta: ImportMeta;
  /** Flag definitions object */
  readonly flags?: Flags;
  /** Description shown above help text (default: package.json description) */
  readonly description?: string | false;
  /** Help text content (supports template literals) */
  readonly help?: string | false;
  /** Version string override (default: package.json version) */
  readonly version?: string | false;
  /** Automatically show help on --help flag */
  readonly autoHelp?: boolean;
  /** Automatically show version on --version flag */
  readonly autoVersion?: boolean;
  /** Custom package.json object */
  readonly pkg?: Record<string, unknown>;
  /** Custom arguments array (default: process.argv.slice(2)) */
  readonly argv?: readonly string[];
  /** Auto-infer argument types from values */
  readonly inferType?: boolean;
  /** Default value for undefined boolean flags */
  readonly booleanDefault?: boolean | null | undefined;
  /** Allow unknown flags (default: true) */
  readonly allowUnknownFlags?: boolean;
  /** Allow parent flags (default: true) */
  readonly allowParentFlags?: boolean;
  /** Number of spaces for help text indentation (default: 2) */
  readonly helpIndent?: number;
  /** @deprecated Hard rejection for unhandled promises */
  readonly hardRejection?: boolean;
}

Result Object

The parsed CLI result with input, flags, and utility functions.

interface Result<Flags extends AnyFlags> {
  /** Non-flag arguments array */
  input: string[];
  /** Flags converted to camelCase excluding aliases */
  flags: CamelCasedProperties<TypedFlags<Flags>> & Record<string, unknown>;
  /** Flags converted to camelCase including aliases */
  unnormalizedFlags: TypedFlags<Flags> & Record<string, unknown>;
  /** The package.json object */
  pkg: PackageJson;
  /** Formatted help text */
  help: string;
  /** Show help text and exit with code (default: 2) */
  showHelp: (exitCode?: number) => never;
  /** Show version text and exit */
  showVersion: () => void;
}

Types

All TypeScript type definitions for comprehensive type safety.

/** Supported flag value types */
type FlagType = 'string' | 'boolean' | 'number';

/** Callback function to determine if a flag is required during runtime */
type IsRequiredPredicate = (
  flags: Readonly<Record<string, any>>, 
  input: readonly string[]
) => boolean;

/** Type-safe flags object with proper inference based on flag definitions */
type TypedFlags<Flags extends Record<string, any>> = {
  [F in keyof Flags]: Flags[F] extends {isMultiple: true}
    ? Flags[F] extends {type: 'string'}
      ? string[]
      : Flags[F] extends {type: 'number'}
        ? number[]
        : Flags[F] extends {type: 'boolean'}
          ? boolean[]
          : unknown[]
    : Flags[F] extends {type: 'string'}
      ? string
      : Flags[F] extends {type: 'number'}
        ? number
        : Flags[F] extends {type: 'boolean'}
          ? boolean
          : unknown
};

Key Features

Argument Processing

  • Automatic parsing: Uses yargs-parser for robust argument processing
  • camelCase conversion: Flag names automatically converted from kebab-case to camelCase
  • Flag negation: Support for --no- prefix to negate boolean flags (e.g., --no-cache sets cache: false)
  • Type inference: Optional automatic type inference for arguments
  • Process title: Automatically sets process title from package.json bin property or package name
  • Promise handling: Makes unhandled rejected promises fail hard instead of silent fail

Flag Types and Validation

  • String flags: Accept string values with optional choices validation
  • Boolean flags: Support true/false with negation and default values
  • Number flags: Accept numeric values with automatic conversion
  • Multiple flags: Accept arrays via repeated flag usage (--flag value1 --flag value2)
  • Required flags: Static or dynamic requirement validation
  • Aliases: Support short flags and alternative names

Help and Version

  • Auto-help: Automatic help generation from help text and flag definitions
  • Auto-version: Automatic version display from package.json
  • Custom help: Support for custom help text with template literals
  • Help formatting: Configurable indentation and automatic text trimming

Error Handling

  • Validation errors: Detailed error reporting for invalid flag values with specific error messages
  • Unknown flags: Optional validation and reporting of unrecognized flags (exits with code 2)
  • Required flags: Missing required flag validation with helpful error messages
  • Choice validation: Validates flag values against predefined choices with clear error reporting
  • Multiple flag validation: Prevents setting single-value flags multiple times
  • Promise rejection: Makes unhandled rejected promises fail hard instead of silent fail
  • Process exit: Automatic process exit on validation failures (code 2) and help/version display (code 0)

Error Examples:

// Unknown flag error
$ my-cli --unknown-flag
// Output: Unknown flag --unknown-flag
// Process exits with code 2

// Missing required flag
flags: {
  output: {
    type: 'string',
    isRequired: true
  }
}
$ my-cli
// Output: Missing required flag --output
// Process exits with code 2

// Invalid choice error
flags: {
  format: {
    type: 'string',
    choices: ['json', 'yaml', 'xml']
  }
}
$ my-cli --format csv
// Output: Unknown value for flag --format: csv. Value must be one of: [json, yaml, xml]
// Process exits with code 2

Advanced Configuration Example:

import meow from 'meow';

const cli = meow({
  importMeta: import.meta,
  description: 'My awesome CLI tool',
  help: `
    Usage
      $ my-tool <command> [options]

    Commands
      build     Build the project
      test      Run tests

    Options
      --config, -c    Configuration file path
      --verbose, -v   Enable verbose output (can be used multiple times)
      --dry-run       Show what would be done without executing
      --no-cache      Disable caching
  `,
  flags: {
    config: {
      type: 'string',
      shortFlag: 'c',
      default: './config.json'
    },
    verbose: {
      type: 'boolean',
      shortFlag: 'v',
      isMultiple: true
    },
    dryRun: {
      type: 'boolean',
      default: false
    },
    cache: {
      type: 'boolean',
      default: true
    }
  },
  booleanDefault: undefined,
  allowUnknownFlags: false,
  helpIndent: 4
});

// Advanced booleanDefault behavior example
const cli2 = meow({
  importMeta: import.meta,
  booleanDefault: undefined, // Exclude undefined boolean flags from result
  flags: {
    rainbow: {
      type: 'boolean',
      default: true,     // This takes precedence over booleanDefault
      shortFlag: 'r'
    },
    unicorn: {
      type: 'boolean',
      default: false,    // This takes precedence over booleanDefault
      shortFlag: 'u'
    },
    sparkles: {
      type: 'boolean'    // Will be excluded if not provided
    }
  }
});

// $ my-cli --rainbow
// Result: { flags: { rainbow: true, unicorn: false } }
// Note: sparkles is excluded since it wasn't provided and booleanDefault is undefined
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/meow@13.2.x
Publish Source
CLI
Badge
tessl/npm-meow badge