YAML vs TOML
YAMLは、すでにそれを使っているエコシステム——Kubernetes、CIパイプライン、Ansible——や、人が読むべき深くネストした文書に選びます。TOMLは、ファイルが曖昧でなく、貼り付けに強く、厳密に型付けされているべきときに選びます。引用符付きの文字列、ネイティブな日付、明示的な構造です。どちらもコメントをサポートし、どちらも設定言語であり、相互の変換は日常的な作業です。
YAML vs TOMLとは
YAMLとTOMLが生まれた理由は同じです。JSONは設定として悲惨——コメントが書けず、すべてのキーに引用符が必須で、括弧を数えなければならない。この共通の出発点から、2つは正反対の賭けに出ました。YAMLは推論による簡潔さに賭けました。引用符はたいてい省略でき、ネストはインデントで表現し、構造は暗黙のうちに。TOMLは明示性に賭けました。文字列には引用符が必須、セクションは[header]で宣言し、何ひとつ推測しない。どちらの賭けも間違いではありません。最適化する失敗モードが違うのです。
YAMLの賭けは、コンパクトで深くまで読みやすいファイルをもたらします。同時に、TOMLには存在しない丸ごとひとつのエラークラスも引き受けます。インデントのミスは文書を静かに作り変え、素のスカラーは推論で型付けされるため、NOのような国コードがbooleanのfalseになります(ノルウェー問題)。TOMLの賭けは、深い階層では長くなるものの、ほとんど誤読のしようがないファイルをもたらします。文法は小さく、2021年以来semver安定の1.0としてバージョン管理されており、値の型は常に構文で宣言されます。
このページは、選択が実際に行われる場面で2つを比較します。構文と構造、型付けと定番の驚き、コメントとアンカー、そしてエコシステム——YAMLならKubernetesとCI、TOMLならCargoとPythonのパッケージング——です。たいていの場合、まずエコシステムがあなたに代わって決めてくれます。
型付けの違いをいちばん速く実感する方法は、同じファイルを両方向に変換することです。YAML→JSON変換ツールが、すべての素のスカラーが何に変わったのかを、ブラウザ内で正確に表示してくれます。
TOMLの明示的なスタイルが何に還元されるのか、気になったことはありませんか?TOML to JSONコンバーターはパースをローカルで実行し、何にもラベルを付けません。推論すべきものが何もないからです。
2つの哲学——推論と宣言
もっとも深い違いは、構造がどこに宿るかです。YAMLでは、構造は空白です。インデントのレベルがネストを定義し、タブは徹底的に禁じられます。TOMLでは、構造は句読点です。[database.pool]のような行がテーブルを宣言し、インデントは純粋に見た目です。このページのほかのすべて——貼り付けの安全性、深い階層での冗長さ、エラーメッセージ——は、この1つの決定から流れてきます。
| 観点 | YAML 1.2 | TOML 1.0 |
|---|---|---|
| 構造 | インデント(スペースのみ。タブは禁止) | [table]ヘッダーとドット区切りのキー |
| 文字列 | 通常は引用符が不要 | 常に引用符付き——"..."または'...' |
| 型付け | パーサーごとに推論。NOはfalseになる | 構文で宣言。推論は一切なし |
| 日時 | タイムスタンプ型。パーサー依存 | ネイティブのRFC 3339日時 |
| アンカー | &アンカーと*エイリアス | なし——値を繰り返すか、生成する |
| 複数文書 | あり——---区切りのストリーム | 1ファイルに1文書 |
| コメント | #から行末まで | #から行末まで |
| 仕様の安定性 | 1.2(2009年)。層を重ねて複雑 | 1.0(2021年)。小さくsemver安定 |
構文——インデント対テーブルヘッダー
浅い設定なら両方の形式が見栄えしますが、深いネストで分かれます。YAMLは構造が深くなるほど静かになっていきます——スペース2つとダッシュで済みます。一方TOMLはレベルごとに1つのヘッダーを書きます。[database.pool.limits]、その次に[database.pool.limits.read]。3階層ならTOMLは単に冗長なだけです。8階層ともなれば、手でまともに書けるのはYAMLだけです。テーブルの配列はこの判定を逆転させます。TOMLの[[products]]ブロックは簡潔でgrepしやすく、マップの長いYAMLリストこそ、列がずれ始める場所です。
貼り付けの安全性は、ここから直接導かれます。YAMLにブロックを貼り付けて1列でも左右にずれると、パースが壊れるか——さらに悪いことに——意味が静かに変わります。ファイルはまだパースでき、何も警告してくれません。TOMLでは、貼り付けたブロックが自分の[header]を運んでくるため、周囲の空白とは無関係に、見出しが示す場所に着地します。
型とノルウェー問題
YAMLはスカラー型を推論しますが、推論には牙があります。多くのパーサーがまだ搭載しているYAML 1.1のルールでは、yes、no、on、offがbooleanになり、NOはfalseになり、1.20と書いたバージョンは数値1.2として届くことがあります。YAML 1.2はルールを削りましたが、パーサーを統一しませんでした。同じファイルがツールごとに違う型を持ち得るのです。防御策は、文字列のままであるべきものは何でも引用符で囲むことです。
TOMLには、間違い得る推論のステップがそもそもありません。引用符があれば文字列、素の数字は整数(読みやすさのためのアンダースコアは許可)、RFC 3339のタイムスタンプはファーストクラスの型です。日付を運ぶ設定では、JSONとYAMLの両方に対する実質的な利点になります。複数行の文字列はどちらにもあります。TOMLの三重引用符の"""ブロックと、YAMLの|と>のスカラーです。
エコシステムと、どちらを選ぶか
エコシステムはすでに縄張りを分け終えています。YAMLはクラウドネイティブとCIを所有します。Kubernetesのマニフェスト、GitHub ActionsとGitLab CI、Ansible、docker-compose、OpenAPIの記述です。TOMLはパッケージングとツールのメタデータを所有します。RustのCargo、Pythonのpyproject.toml、そして曖昧でなくコメントに優しい設定を求めるCLIツールの長いリストです。エコシステムに逆らって選ぶことは、そのツール群と永久に戦うことを意味します。だからこれは、めったに自由な選択ではありません。
自分で選ぶ場面では、深くネストした、人がレビューする文書にはYAMLを、値が曖昧であってはならず、diffが正確で、人と生成器の両方がファイルを編集する場合にはTOMLを選びます。この指針は日常的に逆転します。ほとんどのリポジトリは両方を抱えているからです。ここでリンクしたコンバーターが、どちらの方向でもローカルで橋渡しします。
よくある質問
TOMLはYAMLに取って代わりつつありますか?
いいえ——2つは縄張りを争うのではなく、分け合いました。YAMLが盤石なのは、クラウドネイティブのツール群が要求する場所です。Kubernetes、GitHub Actions、Ansible、docker-compose。TOMLが盤石なのはパッケージングです。Cargo.toml、pyproject.toml、そして最近のCLIツール設定の大半。新しいツールが単純な設定にTOMLを選ぶ傾向は強まっていますが、YAMLからの本格的な大規模移行は起きていません。
TOMLにもノルウェー問題はありますか?
ありません。YAMLは素のスカラーの型を推論するため、NOはbooleanのfalseとしてパースされ、onやoffもbooleanになります。TOMLはすべての文字列に引用符を要求するため、"NO"は曖昧さなく文字列であり、推論は一切起こりません。YAML側の防御策は、TOMLが義務づけるのと同じ規律です。テキストのままであるべき値は何でも引用符で囲むこと。
YAMLとTOMLのコンバーターは、設定ファイルをアップロードしますか?
いいえ。パースと出力はブラウザのタブ内で動きます。アップロード用エンドポイントは存在せず、サイトのContent-Security-Policyはネットワーク要求を自分自身に対してのみ許可します。変換中にDevToolsのNetworkパネルを開いても、外向きのリクエストは見えません。貼り付けたファイルはタブの中にとどまります。
ネストした設定でTOMLがあれほど冗長になるのはなぜですか?
ネストの各レベルに、括弧付きの専用ヘッダーが必要だからです。[database.pool.limits.read]は、最初の値の前に3行分のスコープを宣言します。この冗長さこそが特徴でもあります。セクションはgrepでき、スコープは曖昧でなく、diffには何が動いたかが正確に現れます。設定が8階層にネストするなら、YAMLのインデントのほうが本当に適しています。
YAMLとTOMLの両方でコメントは使えますか?
はい。両方とも、#から行末までがコメントです。設定用途で両者がJSONを駆逐したのは、まさにそのためです。それ以外はほぼすべてが違います。アンカーと複数文書のストリームはYAMLにだけあり、TOMLにはネイティブのRFC 3339の日付と、YAMLがいまだに到達していないsemver安定の1.0文法があります。
コピー&ペーストの安全性ではどちらが上ですか?
TOMLです。YAMLに貼り付けたブロックは、正確に正しいインデントの列に着地しなければならず、そうでないと文書の意味が静かに変わります。パースは通っても、警告は何も出ません。TOMLのブロックは自分の[header]で区切られるため、インデントは見た目にすぎず、貼り付けたセクションは、どこに着地しても見出しの示す意味を保ちます。