TypeScript CLIの候補を実装課題から選ぶ

TypeScriptでCLIを作るとき、「最も高機能なframework」を選ぶことが正解とは限りません。
必要なcommand数、runtime、引数の検証、設定統合、plugin、配布方法を先に決めます。
その後、同じ小さなCLIを候補へ実装して、APIの分かりやすさと運用コストを比べます。
以下は2026年8月に各プロジェクトの公式資料を確認した時点の整理です。
比較の軸を固定する
| 軸 | 確認すること |
|---|---|
| command規模 | 単一commandか、nested commandが増えるか |
| validation | 型変換、条件付き必須、エラー表示をどこで行うか |
| runtime | Node、Deno、複数runtimeのどれを対象にするか |
| UX | help、prompt、table、completionが必要か |
| 設定 | config file、環境変数、既定値をどう統合するか |
| 配布 | npm package、binary、plugin、更新経路が必要か |
parserの機能表だけでなく、利用者が間違いにくいことと、運用者が変更しやすいことを評価します。
5候補の位置づけ
| 候補 | まず調べる用途 | 選定で見る点 |
|---|---|---|
| Citty | 小〜中規模の軽量CLI | TypeScript中心、nested command、lazy loading |
| Commander | Nodeの小〜中規模CLI | 成熟したAPI、help、subcommand |
| Yargs | 引数条件が多いCLI | validation、command builder、config、completion |
| oclif | 配布するCLI製品 | scaffold、plugin、hook、release運用 |
| Cliffy | Denoを第一対象にするCLI | parser、prompt、table、runtime方針 |
機能と依存関係は更新されるため、候補の公式repositoryとdocsを導入時に再確認します。
Cittyは小さな構成から調べる
CittyはUnJSのCLI builderで、Nodeのutil.parseArgsを使う構成を説明しています。
nested commandやlazy loadingを小さなTypeScriptプロジェクトへ組み込む場合の候補になります。
次の条件なら最初に試します。
- UnJSやNuxt周辺と方針を合わせたい
- 依存を増やしたくない
- 起動時にすべてのsubcommandを読み込みたくない
長い運用実績と周辺事例を重視するならCommanderと同じ課題で比較します。
Commanderは素直なNode CLIへ向く
Commander.jsは、option、argument、subcommand、helpを扱う成熟したlibraryです。
既存のNode appへcli.tsを1つ追加するような用途では、APIの形を理解しやすいです。
設定file、対話UI、plugin管理まで必要なら、別の部品を組み合わせる前提で見積もります。
CLIの規模が小さいなら、追加の抽象化より、helpとエラー表示を短時間で整えられるかを優先します。
Yargsは引数の条件を宣言しやすい
Yargsは、解析、型変換、validation、command builder、config file、completionなどを広く扱います。
引数の組み合わせが多いCLIで、条件付き必須や既定値を宣言的に管理したい場合に向きます。
単一commandに少数のoptionだけなら、APIと依存が過剰になる可能性があります。
導入前に、Yargsへ任せるvalidationと、domain logic側で行うvalidationの境界を決めます。
oclifはCLI製品の基盤へ寄せる
oclifは、argument parserよりもCLI製品のframeworkとして設計されています。
TypeScript scaffold、command構成、plugin、hook、test、distributionをまとめたいCLIの候補になります。
次の条件なら検討します。
- 複数OSへ独立製品として配布する
- third-party pluginを受け付ける
- command数と担当teamが増える
- 更新channelとrelease工程を標準化する
小さな社内scriptへ採用すると、必要以上の構成を保守する可能性があります。
Cliffyはruntime方針から選ぶ
CliffyはTypeScript-firstのCLI toolkitで、command、prompt、table、ANSI utilityなどを提供します。
Denoを主対象にし、対話promptとtableを同じ部品群で揃えたい場合に検討します。
Nodeだけを対象にし、argument parserだけで足りるなら、他候補の方が小さいです。
runtime中立性を求めるなら、依存するAPIと配布形式が各runtimeで同じかを小さな実装で確認します。
選定を実装課題へ落とす
候補を次の順で絞ります。
- 単一commandかを確認する
- runtimeと配布形式を決める
- validationとconfig統合の複雑さを見積もる
- plugin、scaffold、release基盤の必要性を決める
- prompt、table、completionの必要性を決める
- 2候補へ同じ最小CLIを実装する
比較用の最小課題は次です。
tool init <name>tool build --watch --format jsontool deploy --env <value>- 共通の
--verbose - 不正なoption組み合わせのvalidation
- shell completion
- 単体test
実装時間だけでなく、helpの読みやすさ、型推論、エラー文、起動時間、bundle size、testのしやすさ、更新状況を記録します。
まとめ
小さなNode CLIはCommanderまたはCittyから調べます。
引数条件、config、completionが増えたらYargsを比較します。
plugin、scaffold、配布、release運用まで製品として扱うならoclifを検討します。
Denoやruntime方針が最優先ならCliffyを候補にします。
「将来必要になる可能性のある機能」ではなく、現在のcommand数と配布方法に合う最小のframeworkを選びます。
