TOML データフォーマット

TOML入門 — 設定ファイルのための読みやすいフォーマット

2026-03-15
目次

データフォーマットシリーズ、今回はTOMLです。CSV/TSVYAMLの落とし穴 と続けてきましたが、「そういえばTOMLちゃんと書いたことないな」という方も多いのではないでしょうか。

TOMLは「設定ファイルのために作られたフォーマット」です。Rustの Cargo.toml やPythonの pyproject.toml で目にする機会が増えていますが、いざ自分で書こうとすると意外と構文がわからない。この記事では、TOMLの基本構文をゼロから整理して、設定ファイルを読み書きできるようになることを目指します。

TOMLとは

TOML(Tom’s Obvious, Minimal Language)は、GitHubの共同創設者であるTom Preston-Wernerが2013年に作ったデータフォーマットです。名前に「Tom’s」が入っているのがチャーミングですね。2021年にバージョン1.0.0がリリースされ、仕様が安定しています。

設計思想は明快で、「人間が読みやすく、コンピュータが解析しやすい、最小限の設定ファイルフォーマット」を目指しています。YAMLのように柔軟すぎず、JSONのように冗長すぎず、ちょうどいいバランスを狙ったフォーマットです。

公式サイトは toml.io で、仕様全文が公開されています。

キーと値の基本

TOMLの基本は キー = 値 のペアです。= の前後にはスペースを入れます。

basics.toml
# 文字列(ダブルクォートで囲む)
name = "Alice"
# 整数
age = 30
# 浮動小数点数
height = 1.65
# 真偽値(true / false のみ。小文字限定)
active = true
# コメントは # で始まる

YAMLと違って、真偽値は truefalse だけです。yes / no / on / off は文字列として扱われます。YAMLの落とし穴 で紹介したノルウェー問題のような暗黙変換は起きません。ここはTOMLの大きな安心ポイントです。

文字列の種類

TOMLには4種類の文字列があります。

strings.toml
# 基本文字列(エスケープシーケンスが使える)
path = "C:\\Users\\alice"
greeting = "Hello,\nWorld!"
# リテラル文字列(エスケープしない。シングルクォート)
regex = '\d+\.\d+'
winpath = 'C:\Users\alice'
# 複数行基本文字列
description = """
これは
複数行の
文字列です。"""
# 複数行リテラル文字列
raw_text = '''
エスケープなしで
そのまま書ける。
バックスラッシュ \ もそのまま。'''

基本文字列では \n\t などのエスケープが効きますが、リテラル文字列ではそのまま文字として扱われます。正規表現やWindowsのファイルパスを書くときにリテラル文字列が便利です。

数値

整数と浮動小数点数は明確に区別されます。

numbers.toml
# 整数
port = 8080
negative = -42
# 可読性のためにアンダースコアで区切れる
large_number = 1_000_000
# 16進数、8進数、2進数
hex = 0xDEADBEEF
oct = 0o755
bin = 0b11010110
# 浮動小数点数
pi = 3.14159
scientific = 5e+22
# 特殊値
infinity = inf
not_a_number = nan

8進数は 0o プレフィックスです。YAMLのように 0 始まりの数値が勝手に8進数に解釈されることはありません。

日時

TOMLは日時型をネイティブでサポートしています。JSONやYAMLでは文字列として扱う日時を、TOMLではファーストクラスの型として表現できます。

datetime.toml
# オフセット付き日時(RFC 3339)
created_at = 2026-03-14T10:30:00+09:00
# ローカル日時(タイムゾーンなし)
updated_at = 2026-03-14T10:30:00
# ローカル日付
birthday = 1990-01-15
# ローカル時刻
alarm = 07:30:00

日付だけ、時刻だけという書き方もできるのが便利です。

テーブル(セクション)

テーブルはキーと値をグループ化する仕組みで、TOMLの中核的な構文です。[テーブル名] のヘッダーで定義します。

tables.toml
[server]
host = "localhost"
port = 8080
[database]
host = "db.example.com"
port = 5432
name = "myapp"

これはJSONに変換すると以下のようになります。

tables.json
{
"server": {
"host": "localhost",
"port": 8080
},
"database": {
"host": "db.example.com",
"port": 5432,
"name": "myapp"
}
}

テーブルはネストもできます。ドットで区切るだけです。

nested-tables.toml
[server.production]
host = "prod.example.com"
port = 443
[server.development]
host = "localhost"
port = 3000

ドットキー

テーブルヘッダーを使わなくても、ドット区切りのキーで階層構造を表現できます。

dotted-keys.toml
# この2つは同じ意味
fruit.apple.color = "red"
# [fruit]
# [fruit.apple]
# color = "red"

フラットに書きたい場合はドットキー、まとまった設定を書く場合はテーブルヘッダー、と使い分けるのがおすすめです。

インラインテーブル

短いテーブルは1行で書くこともできます。

inline-tables.toml
# インラインテーブル
point = { x = 1, y = 2 }
# 通常のテーブルで書くとこう
[point]
x = 1
y = 2

ただし、インラインテーブルは改行できません。要素が多い場合は通常のテーブルを使いましょう。

配列

配列は角括弧 [] で定義します。

arrays.toml
# 基本的な配列
colors = ["red", "green", "blue"]
# 複数行で書くこともできる
ports = [
8080,
8443,
9090,
]
# 末尾カンマOK(ここ嬉しい)
tags = [
"web",
"api",
"backend",
]

末尾カンマが許されているのは地味にありがたいポイントです。要素の追加・削除のときにdiffがきれいになります。

配列テーブル(Array of Tables)

テーブルの配列を定義するには [[テーブル名]] を使います。ダブルブラケットです。

array-of-tables.toml
[[products]]
name = "Hammer"
price = 9.99
[[products]]
name = "Nail"
price = 0.05
sku = 284758393

これはJSONでは以下のように表現されます。

array-of-tables.json
{
"products": [
{ "name": "Hammer", "price": 9.99 },
{ "name": "Nail", "price": 0.05, "sku": 284758393 }
]
}

[[products]] を書くたびに配列に新しい要素が追加されていくイメージです。設定ファイルで「複数のサーバー定義」や「複数の依存関係」を表現するのに使われます。

実際の利用例

TOMLがどんな場面で使われているか、代表的な例を見てみましょう。

Cargo.toml(Rust)

Rustのパッケージマネージャ Cargo の設定ファイルです。TOMLの採用例としてもっとも有名でしょう。

Cargo.toml
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
authors = ["Alice <alice@example.com>"]
description = "A sample Rust application"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
[dev-dependencies]
assert_cmd = "2.0"
[[bin]]
name = "my-app"
path = "src/main.rs"

[dependencies] セクションにパッケージ名と要件を書くシンプルな構成です。serde = { version = "1.0", features = ["derive"] } のようにインラインテーブルを使って、バージョンに加えてfeatureフラグを指定できます。[[bin]] は配列テーブルで、複数のバイナリターゲットを定義できます。

pyproject.toml(Python)

PythonではPEP 518以降、pyproject.toml がプロジェクト設定の標準になりつつあります。

pyproject.toml
[project]
name = "my-package"
version = "1.0.0"
description = "A sample Python package"
requires-python = ">=3.9"
dependencies = [
"requests>=2.28",
"click>=8.0",
]
[project.scripts]
my-cli = "my_package.cli:main"
[tool.ruff]
line-length = 88
target-version = "py39"
[tool.ruff.lint]
select = ["E", "F", "I"]
[tool.pytest.ini_options]
testpaths = ["tests"]

[tool.xxx] のようにツール固有の設定を名前空間で分けられるのが便利です。以前は setup.pysetup.cfgrequirements.txt、各ツールの設定ファイルとバラバラだったものが、1つのファイルにまとまります。

その他の利用例

TOMLは他にもさまざまなツールで採用されています。

  • Hugo(静的サイトジェネレーター): hugo.toml でサイト設定
  • Taplo(TOMLフォーマッター): taplo.toml で設定
  • Deno: deno.toml でプロジェクト設定(JSON も可)
  • Starship(シェルプロンプト): starship.toml で見た目のカスタマイズ

JSON・YAMLとの比較

設定ファイルとしてよく使われる3フォーマットを簡単に比較してみます。

項目TOMLJSONYAML
用途設定ファイルデータ交換設定ファイル / データ
コメント# で可能不可# で可能
型の明確さ高い(暗黙変換なし)高い低い(暗黙変換あり)
真偽値true / false のみtrue / false のみyes / no / on / off なども(v1.1)
日時型ネイティブサポートなし(文字列で表現)なし(文字列で表現)
ネスト表現テーブルヘッダー / ドットキー波括弧のネストインデント
末尾カンマ配列で可能不可(仕様上)N/A
仕様の大きさ小さい小さい大きい

TOMLは設定ファイルに特化しているぶん、仕様がコンパクトで覚えやすいです。一方で、深いネスト構造やツリー状のデータはTOMLだと冗長になりがち。用途に応じた使い分けが大事です。

ざっくりまとめると——

  • TOML: 設定ファイル。フラットから中程度のネストに向いている
  • JSON: API間のデータ交換、構造化データの保存
  • YAML: 深いネスト構造のある設定、CI/CD、Kubernetes

よくあるつまずきポイント

TOMLはYAMLに比べると罠が少ないですが、いくつか注意点があります。

テーブルの定義順

同じテーブルのキーは散らばらせることができません。

invalid-order.toml
# NG: [server] を2回定義できない
[server]
host = "localhost"
[database]
name = "myapp"
[server] # エラー! すでに定義済み
port = 8080

テーブルに属するキーはまとめて書く必要があります。

インラインテーブルの制約

インラインテーブルは後から要素を追加できません。

inline-limitation.toml
# インラインテーブルで定義した後に追加はできない
point = { x = 1, y = 2 }
# point.z = 3 # エラー!

要素の追加が必要な場合は、通常のテーブル記法を使いましょう。

深いネストの冗長さ

TOMLは深いネストが苦手です。3〜4階層くらいまでなら問題ありませんが、それ以上になるとテーブルヘッダーが長くなって読みづらくなります。

deep-nesting.toml
# テーブルヘッダーが長くなりがち
[services.web.production.logging]
level = "info"
format = "json"
[services.web.production.database]
host = "db.example.com"

深いネスト構造が多いなら、YAMLのほうが見やすい場合もあります。適材適所で使い分けましょう。

まとめ

TOMLの基本構文を一通り見てきました。ポイントを振り返ります。

  • TOMLは設定ファイルのために設計されたフォーマット。仕様が小さく、覚えやすい
  • 基本はキーと値のペア。文字列、整数、浮動小数点数、真偽値、日時をサポート
  • テーブル[section])でグループ化、配列テーブル[[array]])で配列を表現
  • 暗黙の型変換がないのでYAMLのような罠が少ない。真偽値は true / false のみ
  • Cargo.toml、pyproject.toml など、モダンなツールで広く採用されている
  • 深いネストには向かない。フラット〜中程度のネスト構造が得意

「設定ファイルを書くなら、まずTOMLを検討する」——これが今のトレンドです。仕様がシンプルなぶん、この記事の内容を押さえればほとんどのTOMLファイルを読み書きできるようになるはずです。

ヒヨリヒヨリ

TOMLって名前からして「トムさんのわかりやすい言語」なんだよね。実際、YAMLみたいな暗黙変換の罠がないから安心して書けるんだ。Cargo.toml とか pyproject.toml を見かけたら、もう怖がらなくて大丈夫!あたし的には末尾カンマOKなところが地味に推しポイント。さあ、手元のプロジェクトで試してみよう!