メインコンテンツへ移動

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.2TOML 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]で区切られるため、インデントは見た目にすぎず、貼り付けたセクションは、どこに着地しても見出しの示す意味を保ちます。

ここで引用した規格はどこで読めますか?

  • YAML 1.2 — YAML仕様 バージョン1.2(改訂1.2.2)
  • TOML 1.0 — TOML仕様 v1.0.0
  • RFC 3339 — インターネット上の日付と時刻:タイムスタンプ
  • YAML 1.1 — YAML仕様 バージョン1.1