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(); // バージョンを表示して終了
類似パッケージとの比較
| 特徴 | meow | commander | yargs | citty |
|---|---|---|---|---|
| 依存パッケージ数 | 0 | 0 | 多数 | 少数 |
| 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 を素早く作りたい場面では最適な選択肢です。