TOML 形式:YAML より簡素な設定ファイルの書き方

約5分

TOML(Tom’s Obvious Minimal Language)は、設定ファイル向けに設計された形式です。YAML より曖昧さが少なく、JSON より人間が書きやすいのが特徴。本記事では TOML の構文と使い所を整理します。

TOML の基本

# コメント

title = "TOML の例"

[owner]
name = "Tom Preston-Werner"
created = 1979-05-27T07:32:00-08:00

[database]
server = "192.168.1.1"
ports = [8001, 8001, 8002]
connection_max = 5000
enabled = true

特徴:

  • INI ファイル風
  • セクション(テーブル)を [name] で表現
  • インデント不要
  • データ型が明確

データ型

TOML がサポートする型:

文字列"hello", 'literal'
数値(整数)42, 0xff, 0o77, 0b1010
数値(浮動小数)3.14, 1e10
真偽値true, false
日時1979-05-27T07:32:00Z
日付1979-05-27
時刻07:32:00
配列[1, 2, 3]
テーブル{ key = "value" }
配列のテーブル[[products]]

文字列の種類

4 種類の文字列:

# 基本(エスケープ可能)
str1 = "I'm a "quoted" string"

# リテラル(エスケープ不可、シングルクォート)
str2 = 'C:Users\nodejs\templates'

# 複数行基本
str3 = """
Roses are red
Violets are blue"""

# 複数行リテラル
str4 = '''
これは
リテラル
'''

テーブル(セクション)

階層を [a.b.c] で表現:

[servers.alpha]
ip = "10.0.0.1"
port = 8080

[servers.beta]
ip = "10.0.0.2"
port = 8081

ネストされたテーブルを表す。インライン形式も可能:

[servers]
alpha = { ip = "10.0.0.1", port = 8080 }
beta = { ip = "10.0.0.2", port = 8081 }

配列のテーブル

リストの各要素がテーブル:

[[products]]
name = "Hammer"
sku = 738594937

[[products]]
name = "Nail"
sku = 284758393
color = "gray"

これは JSON で:

{
	"products": [
		{ "name": "Hammer", "sku": 738594937 },
		{ "name": "Nail", "sku": 284758393, "color": "gray" }
	]
}

日付の扱い

TOML は日付をネイティブサポート:

# UTC タイムゾーン
date1 = 1979-05-27T07:32:00Z

# ローカル日時(タイムゾーン情報なし)
date2 = 1979-05-27T07:32:00

# 日付のみ
date3 = 1979-05-27

# 時刻のみ
time = 07:32:00

YAML と違って曖昧さが少ない。

JSON との変換

同じデータの両方の表現:

title = "TOML"

[database]
server = "localhost"
ports = [8001, 8002]
{
	"title": "TOML",
	"database": {
		"server": "localhost",
		"ports": [8001, 8002]
	}
}

ほぼ無損失で変換可能(コメントは消える)。

YAML との比較

項目TOMLYAML
インデント不要重要
曖昧さ少ない多い(Norway 問題等)
コメントありあり
日付型明確あり(実装依存)
学習コスト
ネストの深さ苦手得意

「設定ファイル向け」と「複雑な構造」で住み分け。

主な採用先

Cargo(Rust)

Cargo.toml

[package]
name = "my-app"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }

Python(pyproject.toml)

PEP 518、PEP 621 で標準化:

[build-system]
requires = ["setuptools >= 61"]
build-backend = "setuptools.build_meta"

[project]
name = "my-package"
version = "1.0.0"
dependencies = [
    "requests >= 2.28",
    "click >= 8.0"
]

setup.py を置き換える流れ。

Hugo(静的サイトジェネレータ)

config.toml(または hugo.toml):

baseURL = "https://example.com"
title = "My Blog"
languageCode = "ja"

[params]
description = "ブログの説明"

落とし穴

キーの重複は禁止

# エラー
name = "first"
name = "second"

YAML や JSON より厳格。

テーブルの順序

[a]
key = 1

[b]
key = 2

[a.c]  # OK:[a] の続きとして扱われる
key = 3

ただし [a] を再開するのは禁止:

[a]
key = 1

[b]
# ...

[a]  # エラー:すでに定義済み
other = 2

文字列のエスケープ

基本文字列で \ が特殊文字:

# エラー(U が予約された)
path = "C:Users"

# OK(リテラル文字列)
path = 'C:Users'

# OK(エスケープ)
path = "C:\Users"

Windows パスを書くときはリテラル文字列を使う。

仕様のバージョン

  • 0.5.0(2018):広く使われている安定版
  • 1.0.0(2021 年 1 月):正式リリース
  • 1.1.0:拡張提案中

新規プロジェクトは TOML 1.0 を選ぶ。

ツール

ライブラリは各言語に揃っている:

  • Rust: toml
  • Python: tomllib(標準ライブラリ、3.11+)、tomli
  • Go: BurntSushi/toml
  • JavaScript: @iarna/tomltoml
  • Java: tomlj

TOML を選ぶべき場面

向いている:

  • 設定ファイル(特に技術系)
  • パッケージマネージャの定義
  • 「フラットな」設定

向いていない:

  • 深いネストが必要なデータ
  • ストリーミング処理
  • 大量のデータ

まとめ

  • TOML は INI ファイル風の設定ファイル形式
  • データ型が明確、曖昧さが少ない
  • Cargo、Python、Hugo で採用
  • YAML より厳格、JSON より人間に優しい
  • 設定向け、データ転送には JSON

TOML を JSON に変換したいときは、本サイトの TOML to JSON 変換ツールが使えます。