JSON Toolkit

JSON, TOML, YAML чи CSON: вибір формату конфігурації

Головне: Конфігураційним файлам потрібні коментарі, дати й багаторядковий текст, і саме тут JSON поступається. Порівняйте JSON, TOML, YAML і CSON та побачте, що конвертація втрачає завжди.

Початковий~9 хв читанняОпубліковано 2026-10-31Оновлено 2026-10-31
Обкладинка порівняння форматів конфігурації JSON, TOML, YAML і CSON

Коротко: використовуйте JSON для машинного обміну й обирайте TOML або YAML для конфігурації, яку підтримує людина, відповідно до екосистеми (YAML для Kubernetes і CI, TOML для пласких структур або рідних дат); повертайтеся до JSONC лише коли не впевнені, чи читач підтримує діалект.

JSON існує для машин, що обмінюються даними; конфігураційний файл пишуть люди для людей. Переплутайте ці два — і отримаєте config.json, який не може вмістити коментар і який ніхто не наважується вкоротити.

1. Почніть із двох різних типів файлів

Обмін даними й конфігурація не поділяють ту саму мету, хоча одна й та сама людина часто пише обидва на одній машині.

Вимір Обмін даними Конфігурація
Хто пише Програма, що серіалізує значення Людина або людина, що редагує згенерований вивід
Хто читає Чужа програма Ваша власна програма
Що важливе Нульова двозначність, розмір, швидкість розбору Читабельність, коментарі, оглядопридатні diff
Частота змін Кожен запит Зрідка, з рев'ю
Ціна помилки Відповідь 500 Сервіс, що не запускається

JSON майже ідеально виграє в лівій колонці: мінімальна граматика, парсер у кожній мові, а відсутність коментарів означає відсутність проблеми «коментар відірвався від значення». У правій колонці його строгість — чисте тертя: без коментарів, без висячих ком, без дат, а багаторядковий текст доводиться згортати в один рядок через \n.

2. Чотири претенденти та їхній синтаксис

  • JSON: визначений RFC 8259 і ECMA-404, рівно з шістьма типами значень: об'єкт, масив, рядок, число, булеве значення й null. Це де-факто стандарт обміну й єдиний формат, що не потребує рішення про вибір.
  • TOML: створений Томом Престон-Вернером, v1.0.0 опубліковано в січні 2021. Його заявлена мета — мінімальний формат конфігурації з очевидною семантикою, що однозначно відображається на хеш-таблицю. Cargo.toml і pyproject.toml використовують його за замовчуванням.
  • YAML: поточна специфікація — 1.2.2. Відступи виражають ієрархію, і він підтримує коментарі, якорі й кілька документів. Маніфести Kubernetes, GitHub Actions і Ansible усі покладаються на нього, ціною великої специфікації й відмінностей реалізацій.
  • CSON: CoffeeScript Object Notation, що пише конфігурацію об'єктними літералами CoffeeScript. config.cson у Atom використовував його. Він підтримує коментарі, ключі без лапок і висячі коми, але його екосистема ніколи не виходила за межі світу JavaScript.

2.1 Порівняння можливостей

Можливість JSON TOML YAML CSON
Коментарі ✗ ✓ # ✓ # ✓ #
Висячі коми ✗ ✓ (масиви, вбудовані таблиці) ✓ (flow-колекції) ✓
Ключі без лапок ✗ ✓ ✓ ✓
Рідна дата-час ✗ (лише рядок) ✓ чотири типи дати-часу ✓ (автоматично розбирається в 1.1) ✗
Багаторядкові рядки ✗ (escape \n) ✓ """ і ''' ✓ блокові й згорнуті скаляри ✓ heredoc
Діапазон цілих Необмежений у специфікації, double на практиці Знакові 64-бітові, мають бути без втрат Довільна точність плюс .inf/.nan Слідує JavaScript
Вкладеність Дужки й квадратні дужки Таблиці, масиви таблиць, ключі з крапками Відступи Відступи
Чутливість до відступів ✗ ✗ ✓ ✓
null ✓ ✗ ✓ ✓
Охоплення інструментів Кожна мова Основні мови Кожна мова, реалізації різняться Лише JavaScript

Дві клітинки варті нотатки. У TOML немає null, що є найпоширенішим збоєм під час конвертації з JSON. Поведінка «рідна дата» YAML означає, що парсер 1.1 автоматично перетворює 2026-10-31 на об'єкт дати, тож тип дрейфує між мовами.

3. Коментарі: єдина слабкість JSON

Спершу висновок: якщо файл підтримує людина й потребує пояснення, чому значення саме таке, не використовуйте стандартний JSON.

Є чотири практичні шляхи, впорядковані за інвазивністю:

  1. Перейдіть на JSONC, тобто стандартний JSON плюс коментарі й висячі коми. settings.json і tsconfig.json у VS Code використовують його. Ціна — читач має використовувати парсер, що розуміє коментарі, як-от jsonc-parser; звичайний JSON.parse зазнає збою. Деталі в JSON5 і JSONC: JSON із коментарями.
  2. Тримайте супутній документ. config.json залишається машинозчитуваним, а config.md пояснює, що означає кожне поле й чому воно має це значення. Обидва лежать у тому самому каталозі й змінюються в тому самому коміті.
  3. Покладіть пояснення в схему. Ключові слова description і $comment JSON Schema можуть документувати поля, але схеми рідко постачаються разом із конфігурацією під час виконання, тож людина, що читає конфігурацію, може їх ніколи не побачити.
  4. Перейдіть на TOML або YAML, дозволяючи самому формату надавати коментарі, які розуміє кожен парсер.
{
  // Фіксовано на 8080: скрипт збірки фронтенду читає цей порт для свого проксі
  "port": 8080,
  // Вимкніть спостереження, щоб не вичерпати inode в CI
  "watch": false
}

JSONC усе ще діалект: розширення лишається .json, але лише деякі інструменти його розуміють. Коли дані залишають команду або перетинають межу сервісу, межу між JSONC і стандартним JSON треба документувати.

4. Дати й багаторядкові рядки: рідна територія TOML

TOML підносить дату-час до повноцінного типу з чотирма варіантами: дата-час із зміщенням, локальна дата-час, локальна дата й локальний час. Багаторядкові рядки мають присвячений синтаксис, що зберігає переведення рядка:

title = "json-toolkit"
created = 2026-10-31T09:00:00+08:00
description = """
A JSON toolkit for developers.
Every operation runs locally in the browser.
"""

Ту саму інформацію в JSON доводиться понижувати дату до рядка й екранувати переведення рядка:

{
  "title": "json-toolkit",
  "created": "2026-10-31T09:00:00+08:00",
  "description": "A JSON toolkit for developers.\nEvery operation runs locally in the browser."
}

У JSON "created" — це просто рядок, що випадково виглядає як дата, тож інформація про тип має жити в контракті поля: обидві сторони мають погодитися, що поле завжди RFC 3339. TOML дає парсеру фактичний об'єкт дати без потреби в словесній домовленості.

YAML теж може тримати багаторядковий текст, але два блокові стилі означають різне: | зберігає переведення рядка, а > згортає їх у пробіли. Оберіть неправильний — і адреса чи інструкція SQL згорнеться в один рядок, помилка, яку дуже важко впіймати на рев'ю.

5. Числа: найбільш проґавлена різниця

Специфікація JSON не обмежує числову точність, але RFC 8259 також попереджає, що сумісність найбезпечніша, коли числа трактують як double IEEE 754. У JavaScript цілі числа понад 2^53 - 1 мовчки втрачають точність:

JSON.parse('{"id":9007199254740993}').id
// 9007199254740992: остання цифра зникла

TOML вимагає, щоб знакові 64-бітові цілі оброблялися без втрат і щоб помилка виникала замість тихого обрізання; дробові слідують binary64 і також можуть бути inf або nan. YAML 1.1 несе старіший тягар: 1:30 розбирається як 90 (шістдесяткова система), а булеві значення приймають yes, no, on і off. Звідси класична «проблема Норвегії», де код країни NO стає false.

Для грошей ніколи не покладайтеся на плаваючу точку в жодному з цих форматів: використовуйте цілі одиниці, рядки або десятковий тип бази даних. Форматування й точність глибше розглянуто в межах конвертації JSON, YAML і XML.

6. Таблиці й вкладеність: жорсткі межі TOML

TOML виражає вкладеність таблицями й масивами таблиць:

[server]
port = 8080

[[routes]]
path = "/parse"
method = "POST"

[[routes]]
path = "/minify"
method = "POST"

Є дві жорсткі межі, які треба знати перед конвертацією:

  • Корінь документа TOML — таблиця, тож документ JSON, чий верхній рівень — масив (як-от [1, 2, 3]), не має законного подання TOML; його треба обгорнути як {"items": [...]};
  • У TOML немає null, тож поле null у JSON треба або відкинути, або замінити порожнім рядком чи маркерним значенням, а семантику перекласти на споживача.

YAML — навпаки: глибина вкладеності необмежена, а якорі плюс ключі злиття дозволяють повторно використовувати фрагменти:

defaults: &defaults
  retries: 3
  timeoutMs: 5000

server:
  <<: *defaults
  port: 8080

Якорі — можливість лише YAML і гарантована втрата під час конвертації: у JSON немає синтаксису посилань, тож розкритий файл зростає, і ніщо не записує, що два розділи раніше були тією самою конфігурацією.

7. Вибір за сценарієм

Сценарій Рекомендація Причина
Публічні API, черги повідомлень, кеші JSON Максимальна універсальність, нульова ціна узгодження
Конфігурація застосунку, пласка й типізована TOML Коментарі, дати, цілі без втрат, стабільна поведінка парсера
Kubernetes, CI, Ansible YAML Екосистема замкнена; зміна формату означає зміну інструментів
VS Code, tsconfig.json JSONC Рідна підтримка, не треба вводити новий формат
Повторне використання фрагментів конфігурації YAML Якорі й ключі злиття — єдиний готовий варіант
Згенероване й лише машинне JSON (мініфікований) Коментарі не потрібні, найкращі розмір і ціна розбору
Застарілі проєкти Atom або CoffeeScript CSON, але плануйте міграцію Екосистема маргінальна, а ціна міграції зростає з часом

Одне практичне правило: нехай формат конфігурації обирає екосистема, а не особисті вподобання. Пишете Rust — це Cargo.toml, розгортаєте в Kubernetes — YAML, будуєте розширення VS Code — JSONC. Лише в новому проєкті без обмежень екосистеми «який зручніше писати» є справжнім питанням.

8. Межі конвертації

Напрямок Інформація, яка завжди втрачається Порада
JSON → TOML null, масиви верхнього рівня, ключі, які неможливо виразити Спершу нормалізуйте структуру й відкиньте порожні поля
TOML → JSON Коментарі, типи дат, inf / nan Конвертуйте дати в рядки RFC 3339
YAML → JSON Коментарі, якорі й ключі злиття, теги, кілька документів Спершу розкрийте якорі, потім конвертуйте документ за документом
JSON → YAML Структурних втрат немає, але рядки дат можуть розбиратися автоматично Беріть рядки дат у лапки
CSON → JSON Коментарі, вирази CoffeeScript Мігруйте один раз; не синхронізуйте в обидва напрямки

Інструменти конвертації гарантують значення, але ніколи не коментарі. Тож не проєктуйте двонаправлений конвеєр, де «JSON — джерело, а YAML — артефакт збірки». Або генеруйте лише в одному напрямку, або підтримуйте один вихідний файл.

9. Чек-лист

  • [ ] Документуйте, які типи файлів використовують який формат, і перелічіть дозволені діалекти;
  • [ ] Надавайте перевагу TOML або YAML для конфігурації, яку підтримує людина, і JSON для машинного обміну;
  • [ ] Зберігайте дати в JSON як рядки RFC 3339 і позначайте формат у схемі;
  • [ ] Подавайте гроші й цілі числа понад 2^53 рядками або дрібними одиницями, ніколи числами з плаваючою точкою;
  • [ ] Перевіряйте кожен формат у CI його власним парсером, ніколи не JSON.parse для YAML;
  • [ ] Мігруйте формати лише в одному напрямку й видаляйте старий файл, щоб два не могли розійтися.

Часті питання

Чому конвертація JSON у TOML зазнає збою на деяких полях?

У TOML немає null, а корінь документа TOML — таблиця, тож поле null у JSON треба відкинути або замінити порожнім рядком чи маркерним значенням, а масив верхнього рівня треба обгорнути як {"items": [...]}. Коментарі, типи дат і inf/nan також втрачаються в протилежному напрямку, тому конвертація має бути односторонньою.

Чи варто тримати два конфігураційні файли в різних форматах?

Ні. Інструменти конвертації гарантують значення, але ніколи коментарі, тож конвеєр, де «JSON — джерело, а YAML — артефакт збірки», розійдеться. Або генеруйте лише в одному напрямку, або підтримуйте один вихідний файл і видаліть старий після міграції.

Як додати коментарі до конфігураційного файлу JSON?

У стандартному JSON немає коментарів. Ви можете перейти на JSONC (діалект VS Code, що читається через jsonc-parser), тримати супутній документ, що пояснює кожне поле, або перейти на TOML чи YAML. Файли, що надсилаються іншим системам, мають залишатися стандартним JSON, а пояснення живуть у документації або схемі.

TOML чи YAML краще для конфігурації застосунку?

Обирайте TOML, коли структура пласка, переважно пари ключ-значення, а рідні дати важливі; його семантика передбачуваніша, а відмінності парсерів менші. Обирайте YAML, коли потрібна глибока вкладеність, кілька документів, повторне використання якорів або коли цільова екосистема надає перевагу YAML, як-от Kubernetes чи CI. Обидва підтримують коментарі, тож справжній розрізнювач — структурна складність і замкненість на екосистемі.

Чому в YAML NO перетворюється на false?

YAML 1.1 трактує yes, no, on, off, y і n як булеві значення, тож код країни Норвегії NO розбирається як false. Це «проблема Норвегії». Уникайте її, використовуючи реалізацію, що слідує YAML 1.2, або беріть у лапки кожен рядок, який можна неправильно прочитати.

Чи CSON усе ще вартий використання?

Не для нових проєктів. CSON залежить від екосистеми CoffeeScript, має мало підтримуваних інструментів і обмежену підтримку редакторів та CI; після припинення підтримки Atom його випадки використання ще звузилися. Якщо проєкт уже має конфігурацію CSON, заплануйте одноразову міграцію в JSON, TOML або YAML, а не додавайте більше.