JSON, TOML, YAML czy CSON: wybór formatu konfiguracji
Podsumowanie: Pliki konfiguracyjne wymagają komentarzy, dat i tekstu wieloliniowego, i tu JSON zawodzi. Porównaj JSON, TOML, YAML i CSON oraz zobacz, co konwersja zawsze gubi.

Najważniejsze: używaj JSON do wymiany między maszynami, a do konfiguracji utrzymywanej przez ludzi wybierz TOML albo YAML zgodnie z ekosystemem (YAML dla Kubernetes i CI, TOML dla płaskich struktur lub natywnych dat); na JSONC przechodź tylko wtedy, gdy nie masz pewności, czy czytnik wspiera dialekt.
JSON istnieje, aby maszyny wymieniały dane; plik konfiguracyjny jest pisany przez ludzi dla ludzi. Pomieszaj te dwa, a dostaniesz
config.json, który nie mieści komentarza i którego nikt nie odważy się przyciąć.
1. Zacznij od dwóch różnych rodzajów plików
Wymiana danych i konfiguracja nie mają tego samego celu, choć ta sama osoba często pisze oba na tej samej maszynie.
| Wymiar | Wymiana danych | Konfiguracja |
|---|---|---|
| Kto pisze | Program serializujący wartość | Człowiek albo człowiek edytujący wygenerowany wynik |
| Kto czyta | Cudzy program | Twój własny program |
| Co się liczy | Zerowa niejednoznaczność, rozmiar, szybkość parsowania | Czytelność, komentarze, diffy nadające się do przeglądu |
| Częstotliwość zmian | Każde żądanie | Od czasu do czasu, z przeglądem |
| Koszt błędu | Odpowiedź 500 | Usługa, która się nie uruchomi |
JSON wypada niemal doskonale w lewej kolumnie: minimalna gramatyka, parser w każdym języku, a brak komentarzy oznacza brak problemu „komentarz oddalił się od wartości”. W prawej kolumnie jego ścisłość jest czystym tarciem: brak komentarzy, brak przecinków końcowych, brak dat, a tekst wieloliniowy trzeba zwinąć do jednej linii z \n.
2. Czterej rywale i ich składnia
- JSON: określony przez RFC 8259 i ECMA-404, z dokładnie sześcioma typami wartości: obiekt, tablica, łańcuch, liczba, wartość logiczna i
null. To de facto standard wymiany i jedyny format, który nie wymaga decyzji wyboru. - TOML: stworzony przez Toma Preston-Wernera, z v1.0.0 opublikowaną w styczniu 2021 roku. Jego deklarowanym celem jest minimalny format konfiguracji o oczywistej semantyce, odwzorowujący się jednoznacznie na tablicę haszującą.
Cargo.tomlipyproject.tomlużywają go domyślnie. - YAML: obecna specyfikacja to 1.2.2. Wcięcia wyrażają hierarchię, a format wspiera komentarze, kotwice i wiele dokumentów. Manifesty Kubernetes, GitHub Actions i Ansible zależą od niego, kosztem dużej specyfikacji i różnic między implementacjami.
- CSON: CoffeeScript Object Notation, który pisze konfigurację literałami obiektowymi CoffeeScript. Używał go
config.csonw Atomie. Wspiera komentarze, klucze bez cudzysłowów i przecinki końcowe, ale jego ekosystem nigdy nie opuścił świata JavaScript.
2.1 Porównanie możliwości
| Możliwość | JSON | TOML | YAML | CSON |
|---|---|---|---|---|
| Komentarze | ✗ | ✓ # |
✓ # |
✓ # |
| Przecinki końcowe | ✗ | ✓ (tablice, tabele inline) | ✓ (kolekcje flow) | ✓ |
| Klucze bez cudzysłowów | ✗ | ✓ | ✓ | ✓ |
| Natywne data-czas | ✗ (tylko łańcuch) | ✓ cztery typy data-czas | ✓ (automatyczne parsowanie w 1.1) | ✗ |
| Łańcuchy wieloliniowe | ✗ (ucieczki \n) |
✓ """ i ''' |
✓ bloki i skalary składane | ✓ heredoc |
| Zakres liczb całkowitych | Nieograniczony w specyfikacji, w praktyce double | 64-bit ze znakiem, musi być bezstratny | Dowolna precyzja plus .inf/.nan |
Zgodny z JavaScript |
| Zagnieżdżenie | Nawiasy klamrowe i kwadratowe | Tabele, tablice tabel, klucze kropkowe | Wcięcia | Wcięcia |
| Wrażliwość na wcięcia | ✗ | ✗ | ✓ | ✓ |
null |
✓ | ✗ | ✓ | ✓ |
| Zasięg narzędzi | Każdy język | Języki głównego nurtu | Każdy język, różne implementacje | Tylko JavaScript |
Dwie komórki zasługują na uwagę. TOML nie ma null, co jest najczęstszą porażką przy konwersji z JSON. Zachowanie „natywnej daty” w YAML oznacza, że parser 1.1 zamienia 2026-10-31 automatycznie w obiekt daty, więc typ dryfuje między językami.
3. Komentarze: jedyna słabość JSON
Najpierw wniosek: jeśli plik utrzymuje człowiek i musi wyjaśnić, dlaczego wartość jest taka, jaka jest, nie używaj standardowego JSON.
Istnieją cztery praktyczne drogi, uporządkowane według inwazyjności:
- Przejdź na JSONC, czyli standardowy JSON plus komentarze i przecinki końcowe. Używają go
settings.jsonitsconfig.jsonw VS Code. Kosztem jest to, że czytnik musi używać parsera świadomego komentarzy, takiego jakjsonc-parser; zwykłyJSON.parsezawodzi. Szczegóły w JSON5 i JSONC: JSON z komentarzami. - Trzymaj dokument towarzyszący.
config.jsonpozostaje czytelny dla maszyn, aconfig.mdwyjaśnia, co znaczy każde pole i dlaczego ma taką wartość. Oba leżą w tym samym katalogu i zmieniają się w tym samym commicie. - Umieść wyjaśnienia w schemacie. Słowa kluczowe
descriptioni$commentw JSON Schema potrafią opisywać pola, ale schematy rzadko trafiają razem z konfiguracją uruchomieniową, więc osoba czytająca konfigurację może nigdy ich nie zobaczyć. - Przejdź na TOML lub YAML, pozwalając samemu formatowi dostarczyć komentarze, które rozumie każdy parser.
{
// Fixed at 8080: the frontend build script reads this port for its proxy
"port": 8080,
// Disable watching to avoid exhausting inodes in CI
"watch": false
}
JSONC to nadal dialekt: rozszerzenie pozostaje .json, ale rozumie je tylko część narzędzi. Gdy dane opuszczają zespół lub przekraczają granicę usługi, linię między JSONC a standardowym JSON trzeba udokumentować.
4. Daty i łańcuchy wieloliniowe: ojczyzna TOML
TOML promuje data-czas do typu pierwszej klasy z czterema wariantami: data-czas z przesunięciem, lokalny data-czas, lokalna data i lokalny czas. Łańcuchy wieloliniowe mają dedykowaną składnię, która zachowuje nowe linie:
title = "json-toolkit"
created = 2026-10-31T09:00:00+08:00
description = """
A JSON toolkit for developers.
Every operation runs locally in the browser.
"""
Ta sama informacja w JSON-ie musi zdegradować datę do łańcucha i escape'ować nowe linie:
{
"title": "json-toolkit",
"created": "2026-10-31T09:00:00+08:00",
"description": "A JSON toolkit for developers.\nEvery operation runs locally in the browser."
}
W JSON-ie "created" to tylko łańcuch, który przypadkiem wygląda jak data, więc informacja o typie musi żyć w kontrakcie pola: obie strony muszą się zgodzić, że pole jest zawsze RFC 3339. TOML daje parserowi faktyczny obiekt daty, bez potrzeby ustaleń słownych.
YAML też potrafi przechowywać tekst wieloliniowy, ale dwa style blokowe znaczą co innego: | zachowuje nowe linie, a > składa je w spacje. Wybierz zły styl, a adres lub instrukcja SQL zwinie się do jednej linii — błąd bardzo trudny do złapania w przeglądzie.
5. Liczby: najczęściej przeoczona różnica
Specyfikacja JSON nie ogranicza precyzji liczb, ale RFC 8259 ostrzega też, że interoperacyjność jest najbezpieczniejsza, gdy liczby traktuje się jako double IEEE 754. W JavaScript liczby całkowite powyżej 2^53 - 1 po cichu tracą precyzję:
JSON.parse('{"id":9007199254740993}').id
// 9007199254740992: the last digit is gone
TOML wymaga, aby 64-bitowe liczby całkowite ze znakiem były obsługiwane bezstratnie i aby zgłaszać błąd, zamiast po cichu obcinać; zmiennoprzecinkowe podążają za binary64 i mogą być też inf lub nan. YAML 1.1 niesie starsze brzemię: 1:30 jest parsowane jako 90 (system sześćdziesiętny), a wartości logiczne akceptują yes, no, on i off. Stąd klasyczny „problem Norwegii”, gdzie kod kraju NO staje się false.
W przypadku pieniędzy nigdy nie polegaj na zmiennoprzecinkowych w żadnym z tych formatów: używaj całkowitych jednostek pomocniczych, łańcuchów lub dziesiętnego typu bazodanowego. Formatowanie i precyzję omówiono głębiej w granicach konwersji JSON, YAML i XML.
6. Tabele i zagnieżdżenie: twarde granice TOML
TOML wyraża zagnieżdżenie przez tabele i tablice tabel:
[server]
port = 8080
[[routes]]
path = "/parse"
method = "POST"
[[routes]]
path = "/minify"
method = "POST"
Ma dwie twarde granice, które trzeba znać przed konwersją:
- Korzeń dokumentu TOML jest tabelą, więc dokument JSON, którego wierzchołkiem jest tablica (na przykład
[1, 2, 3]), nie ma legalnego przedstawienia w TOML; trzeba go opakować jako{"items": [...]}; - TOML nie ma
null, więc polenullz JSON-a trzeba albo usunąć, albo zastąpić pustym łańcuchem lub wartością wartownikową, przenosząc semantykę na konsumenta.
YAML jest przeciwieństwem: głębokość zagnieżdżenia jest nieograniczona, a kotwice plus klucze scalania pozwalają używać ponownie fragmentów:
defaults: &defaults
retries: 3
timeoutMs: 5000
server:
<<: *defaults
port: 8080
Kotwice to możliwość wyłącznie YAML i gwarantowana strata przy konwersji: JSON nie ma składni referencji, więc rozwinięty plik rośnie, a nic nie zapisuje, że dwie sekcje były kiedyś tą samą konfiguracją.
7. Wybór według scenariusza
| Scenariusz | Zalecenie | Powód |
|---|---|---|
| Publiczne API, kolejki komunikatów, cache | JSON | Maksymalna uniwersalność, zerowy koszt negocjacji |
| Konfiguracja aplikacji, płaska i typowana | TOML | Komentarze, daty, bezstratne liczby całkowite, stabilne zachowanie parsera |
| Kubernetes, CI, Ansible | YAML | Ekosystem jest zakleszczony; zmiana formatu oznacza zmianę narzędzi |
VS Code, tsconfig.json |
JSONC | Natywnie wspierany, nie trzeba wprowadzać nowego formatu |
| Ponowne użycie fragmentów konfiguracji | YAML | Kotwice i klucze scalania to jedyna gotowa opcja |
| Generowane i wyłącznie maszynowe | JSON (zminifikowany) | Komentarze nie są potrzebne, najlepszy rozmiar i koszt parsowania |
| Odziedziczone projekty Atom lub CoffeeScript | CSON, ale planuj migrację | Ekosystem jest marginalny, a koszt migracji rośnie z czasem |
Jedna zasada praktyczna: pozwól ekosystemowi wybrać format konfiguracji, a nie osobistemu preferencji. Pisanie w Rust oznacza Cargo.toml, wdrażanie do Kubernetes oznacza YAML, a budowanie rozszerzenia VS Code oznacza JSONC. Tylko w nowym projekcie bez ograniczeń ekosystemu „który pisze się przyjemniej” jest realnym pytaniem.
8. Granice konwersji
| Kierunek | Informacja zawsze tracona | Rada |
|---|---|---|
| JSON → TOML | null, tablice wierzchołkowe, klucze nie do wyrażenia |
Najpierw znormalizuj strukturę i usuń puste pola |
| TOML → JSON | Komentarze, typy dat, inf / nan |
Konwertuj daty do łańcuchów RFC 3339 |
| YAML → JSON | Komentarze, kotwice i klucze scalania, tagi, wiele dokumentów | Najpierw rozwiń kotwice, potem konwertuj dokument po dokumencie |
| JSON → YAML | Brak strat strukturalnych, ale daty w łańcuchach mogą zostać automatycznie sparsowane | Ujmij daty w łańcuchach w cudzysłowy |
| CSON → JSON | Komentarze, wyrażenia CoffeeScript | Migruj raz; nie synchronizuj w dwóch kierunkach |
Narzędzia konwersji gwarantują wartości, nigdy komentarze. Dlatego nie projektuj potoku dwukierunkowego, w którym „JSON jest źródłem, a YAML artefaktem budowania”. Albo generuj tylko w jednym kierunku, albo utrzymuj pojedynczy plik źródłowy.
9. Lista kontrolna
- [ ] Udokumentuj, które typy plików używają którego formatu, i wymień dozwolone dialekty;
- [ ] Preferuj TOML lub YAML dla konfiguracji utrzymywanej przez ludzi, a JSON do wymiany między maszynami;
- [ ] Przechowuj daty w JSON-ie jako łańcuchy RFC 3339 i oznacz format w schemacie;
- [ ] Przedstawiaj pieniądze i liczby całkowite powyżej
2^53jako łańcuchy lub jednostki pomocnicze, nigdy jako zmiennoprzecinkowe; - [ ] Waliduj każdy format w CI jego własnym parserem, nigdy
JSON.parsedla YAML; - [ ] Migruj formaty tylko w jednym kierunku i usuwaj stary plik, aby dwa nie mogły dryfować.
FAQ
Dlaczego konwersja JSON do TOML zawodzi na niektórych polach?
TOML nie ma null, a korzeń dokumentu TOML jest tabelą, więc pole null z JSON-a trzeba usunąć lub zastąpić pustym łańcuchem albo wartownikiem, a tablicę wierzchołkową opakować jako {"items": [...]}. Komentarze, typy dat i inf/nan giną też przy ruchu w przeciwnym kierunku, dlatego konwersja powinna być jednokierunkowa.
Czy utrzymywać dwa pliki konfiguracyjne w różnych formatach?
Nie. Narzędzia konwersji gwarantują wartości, ale nigdy komentarze, więc potok, w którym „JSON jest źródłem, a YAML artefaktem budowania”, będzie dryfować. Albo generuj tylko w jednym kierunku, albo utrzymuj pojedynczy plik źródłowy i usuń stary po migracji.
Jak dodać komentarze do pliku konfiguracyjnego JSON?
Standardowy JSON nie ma komentarzy. Możesz przejść na JSONC (dialekt VS Code, czytany przez jsonc-parser), trzymać dokument towarzyszący wyjaśniający każde pole albo przejść na TOML lub YAML. Pliki wysyłane do innych systemów powinny pozostać standardowym JSON-em, a wyjaśnienia powinny żyć w dokumentacji lub schemacie.
Czy TOML czy YAML lepiej pasuje do konfiguracji aplikacji?
Wybierz TOML, gdy struktura jest płaska, głównie klucz-wartość, i liczą się natywne daty; jego semantyka jest bardziej przewidywalna, a różnice między parserami mniejsze. Wybierz YAML, gdy potrzebujesz głębokiego zagnieżdżenia, wielu dokumentów, ponownego użycia kotwic albo gdy docelowy ekosystem jest YAML-owy, jak Kubernetes lub CI. Oba wspierają komentarze, więc prawdziwym wyróżnikiem jest złożoność strukturalna i zakleszczenie ekosystemu.
Dlaczego NO zamienia się w false w YAML?
YAML 1.1 traktuje yes, no, on, off, y i n jako wartości logiczne, więc kod kraju Norwegii NO jest parsowany jako false. To „problem Norwegii”. Uniknij go, używając implementacji zgodnej z YAML 1.2 albo ujmując w cudzysłowy każdy łańcuch, który mógłby zostać błędnie zinterpretowany.
Czy CSON jest jeszcze wart stosowania?
Nie w nowych projektach. CSON zależy od ekosystemu CoffeeScript, ma mało utrzymywanych narzędzi i ograniczone wsparcie edytorów oraz CI; po zaprzestaniu utrzymania Atomu jego zastosowania skurczyły się jeszcze bardziej. Jeśli projekt ma już konfigurację CSON, zaplanuj jednorazową migrację do JSON, TOML lub YAML, zamiast dokładać więcej.