meow の使い方

CLI app helper

v14.1.0/週MITCLI
AI生成コンテンツ

この記事はAIによって生成されました。内容の正確性は保証されません。最新の情報は公式ドキュメントをご確認ください。

meow の使い方 — Node.js CLIアプリを簡単に構築するヘルパー

一言でいうと

meow は、Node.js で CLI アプリケーションを作る際の引数パース・ヘルプ表示・バージョン表示などの定型処理をまとめて提供する軽量ヘルパーです。依存パッケージがゼロで、ESM ネイティブに対応しています。

どんな時に使う?

  • 自作の CLI ツールを素早く作りたいとき--help--version の処理、フラグのパースを数行で実装できます
  • package.json の情報を自動で活用したいとき — バージョンや説明文を自動的に読み取ってヘルプに反映します
  • サブコマンドを持つ CLI を構築したいときcommands オプションでコマンドベースのルーティングが可能です(v14〜)

インストール

# npm
npm install meow

# yarn
yarn add meow

# pnpm
pnpm add meow

注意: meow v14 は ESM 専用パッケージです。"type": "module"package.json に必要です。CommonJS(require)では使用できません。

基本的な使い方

最もシンプルなパターンを示します。

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

const cli = meow(`
  Usage
    $ greet <name>

  Options
    --shout, -s  大文字で出力する

  Examples
    $ greet world --shout
    HELLO, WORLD!
`, {
  importMeta: import.meta,
  flags: {
    shout: {
      type: 'boolean',
      shortFlag: 's',
      default: false,
    },
  },
});

const name = cli.input.at(0) ?? 'stranger';
const message = `Hello, ${name}!`;

console.log(cli.flags.shout ? message.toUpperCase() : message);
$ greet world --shout
HELLO, WORLD!

$ greet --help
# => ヘルプテキストが表示される

$ greet --version
# => package.json の version が表示される

importMeta: import.meta必須です。meow はこれを使って最寄りの package.json を探索します。

よく使う API

1. 返り値オブジェクトの構造

meow() の返り値には以下のプロパティが含まれます。

import meow from 'meow';

const cli = meow({
  importMeta: import.meta,
  flags: {
    name: { type: 'string', shortFlag: 'n' },
    verbose: { type: 'boolean', shortFlag: 'v' },
  },
});

// フラグ以外の引数(位置引数)
console.log(cli.input);
// => ['arg1', 'arg2']

// パースされたフラグ(camelCase)
console.log(cli.flags);
// => { name: 'foo', verbose: true }

// エイリアスを含むフラグ
console.log(cli.unnormalizedFlags);

// 読み込まれた package.json
console.log(cli.pkg.version);

2. flags の型指定と choices によるバリデーション

フラグに許容値を制限できます。不正な値が渡されるとエラーメッセージを表示して終了します。

const cli = meow({
  importMeta: import.meta,
  flags: {
    color: {
      type: 'string',
      choices: ['red', 'green', 'blue'],
      default: 'blue',
    },
    count: {
      type: 'number',
      default: 1,
    },
  },
});

console.log(cli.flags.color); // => 'red' | 'green' | 'blue'
console.log(cli.flags.count); // => number

3. isMultiple — 同一フラグの複数指定

const cli = meow({
  importMeta: import.meta,
  flags: {
    tag: {
      type: 'string',
      shortFlag: 't',
      isMultiple: true,
    },
  },
});

// $ my-cli -t foo -t bar
console.log(cli.flags.tag);
// => ['foo', 'bar']

注意: スペース区切りやカンマ区切り(-t foo,bar)には対応していません。フラグを複数回指定する必要があります。

4. isRequired — 必須フラグ・必須入力

フラグや入力を必須にできます。関数を渡して実行時に動的に判定することも可能です。

const cli = meow({
  importMeta: import.meta,
  input: {
    type: 'string',
    isRequired: true, // 位置引数が1つ以上必須
  },
  flags: {
    output: {
      type: 'string',
      shortFlag: 'o',
      isRequired: (flags, input) => {
        // --format が指定されたら --output も必須にする
        return Boolean(flags.format);
      },
    },
    format: {
      type: 'string',
    },
  },
});

5. commands — サブコマンドのルーティング

v14 で追加された commands オプションにより、サブコマンドベースの CLI を構築できます。

const cli = meow({
  importMeta: import.meta,
  commands: ['init', 'build', 'serve'],
  flags: {
    verbose: {
      type: 'boolean',
      shortFlag: 'v',
    },
  },
});

switch (cli.command) {
  case 'init': {
    // サブコマンド用に再パースも可能
    const initCli = meow({
      importMeta: import.meta,
      argv: cli.input, // 残りの引数を渡す
      flags: {
        template: { type: 'string', default: 'default' },
      },
    });
    console.log('init with template:', initCli.flags.template);
    break;
  }
  case 'build':
    console.log('building...');
    break;
  case 'serve':
    console.log('serving...');
    break;
  default:
    cli.showHelp(0);
}
$ my-cli --verbose init --template react
# => cli.command === 'init', cli.flags.verbose === true
# => initCli.flags.template === 'react'

親フラグ(--verbose)はコマンドのに置く必要がある点に注意してください。

6. showHelp / showVersion

プログラムから任意のタイミングでヘルプやバージョンを表示できます。

if (!cli.input.length && !cli.command) {
  cli.showHelp(0); // 終了コード 0 で終了(デフォルトは 2)
}

cli.showVersion(); // バージョンを表示して終了

類似パッケージとの比較

特徴meowcommanderyargscitty
依存パッケージ数00多数少数
ESM 対応✅ ネイティブ
TypeScript 型推論基本的✅ 良好✅ 良好✅ 良好
サブコマンドシンプル(v14〜)充実充実充実
ヘルプ自動生成テンプレート手書きフラグ定義から自動フラグ定義から自動フラグ定義から自動
学習コスト低い中程度高い低い
設計思想最小限・シンプル宣言的・多機能多機能・高カスタマイズモダン・軽量

選定の目安:

  • シンプルな CLI をサッと作りたい → meow
  • サブコマンドが多く、ヘルプを自動生成したい → commander / yargs
  • Nuxt/Nitro エコシステムで使いたい → citty

注意点・Tips

ESM 必須

meow v14 は Pure ESM パッケージです。require() では読み込めません。package.json"type": "module" を設定するか、.mjs 拡張子を使用してください。

importMeta は省略不可

importMeta: import.meta を渡さないとエラーになります。これは package.json の自動探索に使われます。

フラグ名は camelCase で定義、kebab-case で入力

// 定義
flags: { myFlag: { type: 'string' } }

// 使用(どちらも OK)
// $ cli --my-flag value
// $ cli --myFlag value

booleanDefault の undefined に注意

booleanDefault: undefined を明示的に指定すると、argv に含まれない boolean フラグは結果オブジェクトから除外されます。キーを省略した場合(デフォルト false)とは挙動が異なります。

TypeScript での型安全な利用

meow は返り値の型推論が限定的です。フラグの型を厳密に扱いたい場合は、返り値を受け取った後にアサーションや Zod 等で追加バリデーションすることを推奨します。

import meow from 'meow';

const cli = meow({
  importMeta: import.meta,
  flags: {
    port: { type: 'number', default: 3000 },
  },
});

// 型を明示的に扱う
const port: number = cli.flags.port as number;

ヘルプテキストはテンプレートリテラルで書く

インデントは自動調整されるため、テンプレートリテラル内のインデントを気にする必要はありません。先頭・末尾の改行もトリムされます。

まとめ

meow は「CLI ツールに必要な最低限の機能を、依存ゼロで提供する」という明確な設計思想を持つパッケージです。引数パース・ヘルプ表示・バージョン表示といった定型処理を数行で実装でき、v14 ではサブコマンド対応も加わりました。複雑なサブコマンド体系や高度な型推論が必要な場合は commander や yargs を検討すべきですが、シンプルな CLI を素早く作りたい場面では最適な選択肢です。