JSON, TOML, YAML чи CSON: вибір формату конфігурації
Головне: Конфігураційним файлам потрібні коментарі, дати й багаторядковий текст, і саме тут JSON поступається. Порівняйте 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.
Є чотири практичні шляхи, впорядковані за інвазивністю:
- Перейдіть на JSONC, тобто стандартний JSON плюс коментарі й висячі коми.
settings.jsonіtsconfig.jsonу VS Code використовують його. Ціна — читач має використовувати парсер, що розуміє коментарі, як-отjsonc-parser; звичайнийJSON.parseзазнає збою. Деталі в JSON5 і JSONC: JSON із коментарями. - Тримайте супутній документ.
config.jsonзалишається машинозчитуваним, аconfig.mdпояснює, що означає кожне поле й чому воно має це значення. Обидва лежать у тому самому каталозі й змінюються в тому самому коміті. - Покладіть пояснення в схему. Ключові слова
descriptionі$commentJSON Schema можуть документувати поля, але схеми рідко постачаються разом із конфігурацією під час виконання, тож людина, що читає конфігурацію, може їх ніколи не побачити. - Перейдіть на 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, а не додавайте більше.