JSON、YAML、TOMLはソフトウェア開発で最も人気のある3つの設定フォーマットです。それぞれに異なる強みとトレードオフがあります。このガイドでは、プロジェクトに最適なフォーマットを選ぶための包括的な比較を提供します。
各フォーマットの概要
JSON(JavaScript Object Notation)
JSONは2000年代初頭にDouglas Crockfordによって導入されました。Web API、package.json、tsconfig.jsonなどのデファクトスタンダードです。
YAML(YAML Ain't Markup Language)
YAMLは2001年に提案され、人間が読みやすいことを目指して設計されました。Docker Compose、Kubernetes、Ansible、CI/CDパイプラインで広く使われています。
TOML(Tom's Obvious Minimal Language)
TOMLは2013年にTom Preston-Wernerによって作られた最小限で曖昧さのない設定フォーマットです。Rust(Cargo.toml)、Python(pyproject.toml)、Hugoの標準です。
構文の比較
同じ設定を3つのフォーマットで表現します:
JSON
{
"server": {
"host": "localhost",
"port": 8080,
"debug": true
},
"database": {
"host": "db.example.com",
"port": 5432,
"name": "myapp",
"credentials": {
"username": "admin",
"password": "secret"
}
},
"features": ["auth", "logging", "cache"],
"max_connections": 100
}YAML
# Server configuration
server:
host: localhost
port: 8080
debug: true
# Database settings
database:
host: db.example.com
port: 5432
name: myapp
credentials:
username: admin
password: secret
features:
- auth
- logging
- cache
max_connections: 100TOML
# Server configuration
max_connections = 100
features = ["auth", "logging", "cache"]
[server]
host = "localhost"
port = 8080
debug = true
[database]
host = "db.example.com"
port = 5432
name = "myapp"
[database.credentials]
username = "admin"
password = "secret"機能比較
| 機能 | JSON | YAML | TOML |
|---|---|---|---|
| コメント | なし | あり(#) | あり(#) |
| データ型 | string, number, boolean, null, array, object | string, int, float, bool, null, date, array, map + カスタムタグ | string, integer, float, boolean, datetime, array, table |
| 可読性 | 中程度——波括弧と引用符がノイズになる | 高い——インデントベースのきれいな構文 | 高い——INIライクでセクションが明確 |
| 厳密さ | 非常に厳密——末尾カンマやコメント不可 | 緩い——暗黙的な型推論が予想外の動作を引き起こす | 厳密——明示的な型、曖昧さ最小限 |
| ツールサポート | 優秀——全言語でネイティブパーサー対応 | 良好——主要言語すべてにパーサーあり | 良好——成長中、Rust/Python/Goで強い |
| 複数行文字列 | なし(\n エスケープシーケンスを使用) | あり(| リテラル、> フォールド) | あり(トリプルクォート文字列) |
各フォーマットの使いどころ
JSON を使う場合...
- REST APIの構築または利用
- package.jsonやtsconfig.jsonでの作業
- 機械が主に読むデータの保存
- 最も幅広いツールサポートが必要な場合
- 異なるプログラミング言語間のデータ交換
// Typical JSON use cases
// package.json
{
"name": "my-app",
"version": "1.0.0",
"scripts": {
"dev": "next dev",
"build": "next build"
}
}
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true
}
}YAML を使う場合...
- Docker ComposeやKubernetesマニフェストの作成
- CI/CDパイプラインの設定
- AnsibleやHelmの使用
- 設定にコメントが必要な場合
- 人間の可読性が最優先
# Docker Compose
services:
web:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
# GitHub Actions
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm testTOML を使う場合...
- Rustプロジェクトの設定(Cargo.toml)
- Pythonプロジェクトの設定(pyproject.toml)
- Hugoの使用
- 暗黙的な型変換のない明確なフォーマットが必要な場合
- 設定に明確なセクション/グループがある場合
# Cargo.toml (Rust)
[package]
name = "my-app"
version = "0.1.0"
edition = "2021"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
# pyproject.toml (Python)
[project]
name = "my-package"
version = "1.0.0"
requires-python = ">=3.9"
[tool.ruff]
line-length = 88
target-version = "py39"よくある落とし穴
YAML:インデントの問題
YAMLはインデントで構造を定義します。タブとスペースの混在やインデントレベルの不一致は、最も一般的なエラーの原因です。
# BAD: mixing tabs and spaces (invisible but breaks YAML)
services:
web: # tab character - YAML error!
image: nginx
# BAD: inconsistent indentation
services:
web:
image: nginx # 4 spaces here
ports: # 2 spaces here - error!
- "80:80"
# GOOD: consistent 2-space indentation
services:
web:
image: nginx
ports:
- "80:80"YAML:「ノルウェー問題」
YAML 1.1では、引用符なしのNO、yes、on、offはブール値として解釈されます。国コード「NO」(ノルウェー)はfalseになります。
# The "Norway Problem" - YAML 1.1
countries:
- name: Norway
code: NO # Parsed as boolean false!
- name: Sweden
code: SE # Parsed as string "SE"
- name: Finland
code: FI # Parsed as string "FI"
# Other surprising boolean values in YAML 1.1:
truthy: yes # boolean true
falsy: no # boolean false
enabled: on # boolean true
disabled: off # boolean false
positive: TRUE # boolean true
negative: False # boolean false
# FIX: Always quote values that could be misinterpreted
countries:
- name: Norway
code: "NO" # Now correctly a string
- name: Sweden
code: "SE"
settings:
enabled: "yes" # Now correctly a stringJSON:末尾カンマ
JSONは末尾カンマを許可しません。最後の要素の後にカンマを追加するとパースエラーになります。
// BAD: trailing comma after last element
{
"name": "my-app",
"version": "1.0.0",
"private": true, // <-- trailing comma = PARSE ERROR
}
// BAD: trailing comma in array
{
"colors": [
"red",
"green",
"blue", // <-- trailing comma = PARSE ERROR
]
}
// GOOD: no trailing commas
{
"name": "my-app",
"version": "1.0.0",
"private": true
}TOML:ネストされたテーブル構文
TOMLでの深いネスト構造は冗長になることがあります。各レベルに独自の[section.subsection]ヘッダーが必要です。
# TOML: deeply nested config can be verbose
[server]
host = "localhost"
[server.ssl]
enabled = true
[server.ssl.certificates]
cert = "/path/to/cert.pem"
key = "/path/to/key.pem"
[server.ssl.certificates.ca]
bundle = "/path/to/ca-bundle.pem"
# The same in YAML is more compact:
# server:
# host: localhost
# ssl:
# enabled: true
# certificates:
# cert: /path/to/cert.pem
# key: /path/to/key.pem
# ca:
# bundle: /path/to/ca-bundle.pem
# TOML inline tables can help for shallow nesting:
[server]
host = "localhost"
ssl = { enabled = true, cert = "/path/to/cert.pem" }変換ツール
フォーマット間の切り替えが必要ですか?無料オンラインコンバーターをご利用ください:
よくある質問
JSON、YAML、TOMLのうちパースが最も速いのは?
JSONは一般的に最も高速です。シンプルで厳密な文法のため、パーサーが高度に最適化されています。TOMLも明確な構文のため高速です。YAMLは複雑な仕様のため最も遅いです。
JSONでコメントは使えますか?
標準JSON(RFC 8259)はコメントをサポートしていません。JSON5やJSONCが拡張としてコメントをサポートしますが、非標準です。
なぜYAMLは「NO」をfalseとして扱うのですか?
YAML 1.1ではyes/no、on/off、true/falseがブール値として認識されます。「NO」(ノルウェー)はfalseになります。常に引用符で囲んでください。
TOMLはYAMLより設定ファイルに適していますか?
TOMLはシンプルな設定に適しています。YAMLは深いネスト構造に優れています。エコシステムによります。
フォーマット間の変換でデータは失われますか?
一般的なデータ構造では変換は無損失です。YAMLアンカーやコメントなどのフォーマット固有の機能はJSONへの変換時に失われます。