YAML बनाम JSON बनाम TOML: किस कॉन्फ़िगरेशन फ़ॉर्मेट का उपयोग कब करें
हर प्रोजेक्ट को अंततः एक कॉन्फ़िग समस्या का सामना करना पड़ता है। आपको डेटाबेस क्रेडेंशियल स्टोर करने हैं, डिप्लॉयमेंट एनवायरनमेंट परिभाषित करने हैं, CI पाइपलाइन का वर्णन करना है, या डिपेंडेंसी जोड़नी हैं — और किसी को एक फ़ॉर्मेट चुनना होगा। JSON? YAML? TOML? यह चुनाव मनमाना लगता है जब तक यह आपको परेशान न करे।
Docker Compose फ़ाइलें YAML होती हैं। package.json JSON है। Rust का डिपेंडेंसी मेनिफेस्ट (Cargo.toml) TOML है। Python पैकेजिंग (pyproject.toml) TOML है। GitHub Actions वर्कफ़्लो YAML हैं। ये यादृच्छिक नहीं हैं — प्रत्येक फ़ॉर्मेट ने अपने डोमेन में विशिष्ट कारणों से स्वीकृति की लड़ाई जीती। इन कारणों को समझने से आप "टेम्पलेट में जो था" के बजाय सोच-समझकर निर्णय ले सकते हैं।
यह लेख एक निर्णय गाइड है। इसके अंत तक, आप प्रत्येक फ़ॉर्मेट के वास्तविक trade-offs जानेंगे, YAML के उन सटीक खतरों को देखेंगे जिन्होंने प्रोडक्शन में घटनाएं पैदा की हैं, और चुनाव के लिए एक स्पष्ट ढांचा पाएंगे।
सामान्य पूर्वज: INI फ़ाइलें
आधुनिक प्रतिस्पर्धियों में गोता लगाने से पहले, INI फ़ाइलों पर तीस सेकंड बिताना उचित है — वह फ़ॉर्मेट जिस पर तीनों किसी न किसी अर्थ में प्रतिक्रिया कर रहे हैं।
INI फ़ाइलें ऐसी दिखती हैं:
[database]
host = localhost
port = 5432
name = mydb
[server]
port = 8080
debug = trueसरल, मानव-पठनीय, सेक्शन और कमेंट का समर्थन करती हैं। समस्याएं उतनी ही सरल हैं: कोई मानक स्पेसिफिकेशन नहीं (प्रत्येक पार्सर edge cases को अलग तरह से interpret करता है), एक स्तर से आगे कोई नेस्टेड संरचना नहीं, कोई array नहीं, कोई explicit types नहीं। सब कुछ एक string है जब तक आपका एप्लिकेशन अन्यथा न तय करे।
INI 1997 में php.ini के लिए ठीक था। 2026 में Kubernetes डिप्लॉयमेंट का वर्णन करने के लिए ठीक नहीं है। लेकिन इसने सही लक्ष्य पहचाने — मानव संपादन क्षमता और कमेंट — जिन्हें आधुनिक फ़ॉर्मेट ने या तो विरासत में लिया या छोड़ दिया।
JSON: डेटा की Lingua Franca
JSON (JavaScript Object Notation) 2000 के दशक की शुरुआत में मानकीकृत हुआ और APIs के लिए प्रमुख वायर फ़ॉर्मेट बन गया। इसकी ताकत इसकी सीमाओं से आती है।
JSON क्या सही करता है
JSON में ठीक छह value types हैं: string, number, boolean, null, array और object। स्पेसिफिकेशन अस्पष्ट नहीं है। प्रत्येक compliant JSON पार्सर एक ही दस्तावेज़ को समान रूप से parse करेगा। कोई आश्चर्य नहीं।
{
"database": {
"host": "localhost",
"port": 5432,
"ssl": true
},
"allowed_origins": ["https://example.com", "https://api.example.com"],
"timeout_ms": null
}port का प्रकार निर्विवाद रूप से एक number है। ssl निर्विवाद रूप से एक boolean है। allowed_origins निर्विवाद रूप से strings की एक array है। एक JSON पार्सर इसे गलत नहीं पढ़ सकता।
JSON सर्वव्यापी भी है। हर भाषा में एक standard library JSON पार्सर है। ब्राउज़र इसे natively parse करते हैं। PostgreSQL जैसे डेटाबेस में native JSON columns हैं। यह उन सिस्टम के बीच डेटा एक्सचेंज के लिए lowest-common-denominator फ़ॉर्मेट है जो runtime share नहीं करते।
कॉन्फ़िगरेशन के लिए JSON क्या गलत करता है
JSON में comment syntax नहीं है। यह Douglas Crockford (JSON के निर्माता) का एक जानबूझकर डिज़ाइन निर्णय है, इस आधार पर कि data formats में comments लोगों को उनमें parsing directives डालने के लिए प्रोत्साहित करते हैं, जो format की portability को खराब करता है।
API responses के लिए यह एक अच्छा सिद्धांत है। Config files के लिए यह एक गंभीर समस्या है। Config files को comments की आवश्यकता है। आपको बताना होगा कि timeout_ms 30000 क्यों है न कि 10000। आपको यह चिह्नित करना होगा कि कौन से fields बदलने के लिए सुरक्षित हैं। आपको एक नोट छोड़ना होगा जो कहे "staging पर इसे 100 से ऊपर सेट न करें।"
वैकल्पिक उपाय सभी बुरे हैं। कुछ टीमें "_comment" fields का उपयोग करती हैं। कुछ JSON5 (comments के साथ एक superset) का उपयोग करती हैं और उम्मीद करती हैं कि उनके tools इसे संभाल लेंगे। कुछ JSONC (JSON with Comments, जो VS Code के settings.json से लोकप्रिय हुआ) का उपयोग करती हैं। इनमें से कोई भी standard JSON नहीं है।
JSON कॉन्फ़िगरेशन के लिए verbose भी है। Trailing commas की अनुमति नहीं है, जो fields को reorder करते समय लगातार syntax errors पैदा करता है। हर string key के लिए double quotes आवश्यक हैं। कोई multiline string syntax नहीं है — एक लंबे shell command को एक लाइन पर escape करना होगा।
JSON इनके लिए उपयुक्त है: API responses, services के बीच data interchange, package manifests जो मुख्यतः machine-written हैं (package.json, composer.json), और जहां भी heterogeneous सिस्टम में guaranteed parse consistency चाहिए।
आप JSON को ऑनलाइन validate कर सकते हैं ताकि syntax errors application तक पहुंचने से पहले पकड़े जाएं — जो आप जितना सोचते हैं उससे ज़्यादा मायने रखता है, क्योंकि एक missing comma या trailing bracket JSON पार्सर को पूरी तरह से तोड़ देगा।
YAML: शक्ति और खतरा
YAML (YAML Ain't Markup Language) को XML का मानव-अनुकूल विकल्प बनाने के लिए डिज़ाइन किया गया था। यह expressive, readable और DevOps tooling में गहराई से उपयोग किया जाता है। यह आम उपयोग में सबसे खतरनाक config format भी है।
YAML क्या सही करता है
YAML comments (#) की अनुमति देता है। यह unquoted values से types infer करता है, इसलिए आप "port": 5432 के बजाय port: 5432 लिख सकते हैं। यह clean heredoc-जैसे syntax के साथ multiline strings का समर्थन करता है। यह concise है: indentation braces और brackets की जगह लेती है।
database:
host: localhost
port: 5432
ssl: true
allowed_origins:
- https://example.com
- https://api.example.com
# यह एक comment है जो बताता है कि timeout high क्यों है
timeout_ms: 30000CI/CD configurations के लिए — GitHub Actions, GitLab CI, CircleCI — YAML की nested structures को comments के साथ cleanly express करने की क्षमता वास्तव में उपयोगी है। एक GitHub Actions workflow file अक्सर nested conditions, matrix strategies और environment variable blocks के साथ सैकड़ों lines तक फैली होती है। JSON अपठनीय होगा। TOML deeply nested structures के लिए awkward होगा।
YAML के छुपे खतरे
YAML का type inference वह जगह है जहां चीजें गलत होती हैं। पार्सर unquoted values को देखता है और तय करता है कि वे किस प्रकार की हैं। इसके फैसले हमेशा वैसे नहीं होते जैसा आप उम्मीद करते हैं।
Norway Problem. YAML 1.1 में (जो अधिकांश पार्सर implement करते हैं — YAML 1.2 नहीं), एक bare NO को boolean false के रूप में parse किया जाता है। no, No, n, N, false, False, FALSE, off, Off और OFF भी। ISO 3166-1 country codes की सूची में Norway के लिए NO शामिल है। Country code list वाली एक config file चुपचाप Norway को false में बदल देगी।
# YAML 1.1 — पार्सर वास्तव में क्या देखता है
country: NO # → false (boolean)
enabled: yes # → true (boolean)
mode: on # → true (boolean)
debug: off # → false (boolean)इसका समाधान हर उस चीज़ को quote करना है जो string होनी चाहिए: country: "NO"। लेकिन YAML की पूरी आकर्षण यह है कि आपको चीजों को quote नहीं करना पड़ता। आश्चर्यों से बचने के लिए quotes की आवश्यकता format की readability advantage को कमज़ोर करती है।
Octal integers. YAML 1.1 में, 0 से शुरू होने वाला number octal माना जाता है। File permissions आमतौर पर octal में लिखी जाती हैं: chmod: 0755। एक YAML पार्सर 0755 को decimal number 493 के रूप में पढ़ता है, न कि 755 के रूप में। इसने वास्तविक deployment scripts को तोड़ा है।
# YAML 1.1 — octal interpretation
file_mode: 0755 # → 493 (octal 0755 का decimal equivalent)Multiline string ambiguity. YAML multiline strings के लिए कई syntaxes प्रदान करता है — literal block (|), folded block (>), और inline। ये newlines, trailing whitespace और indentation के संबंध में अलग तरह से व्यवहार करते हैं। गलत वाला चुनने पर चुपचाप गलत string produce होती है।
# Literal block — newlines को preserve करता है
command: |
npm install
npm run build
# Folded block — newlines spaces बन जाते हैं (long prose के लिए उपयोगी)
description: >
This is a long description that will be
folded into a single line with spaces.Tabs बनाम spaces. YAML indentation के लिए tab characters की अनुमति नहीं देता। एक editor जो चुपचाप tabs insert करता है, एक parse error produce करेगा — या इससे भी बुरा, tab stop setting के आधार पर एक अलग parse।
YAML 1.2 ने इनमें से कई समस्याओं को ठीक किया (boolean value list सहित), लेकिन अधिकांश tools अभी भी 1.1 implement करते हैं। जब आप YAML उपयोग करते हैं, आप उस पार्सर के लिए लिख रहे हैं जो आपकी toolchain ship करती है, जो आपकी assumptions से match कर भी सकती है और नहीं भी।
TOML: कॉन्फ़िगरेशन के लिए डिज़ाइन किया गया
TOML (Tom's Obvious Minimal Language) 2013 में Tom Preston-Werner (GitHub के co-founder) द्वारा विशेष रूप से एक config file format के रूप में बनाया गया था जिसे humans लिख सकें और machines बिना ambiguity के parse कर सकें।
TOML क्या सही करता है
TOML में explicit, unambiguous types हैं। एक string हमेशा quoted होती है। एक number हमेशा number होता है। एक boolean हमेशा true या false होता है (lowercase, कोई aliases नहीं)। Bare values से कोई type inference नहीं है, इसलिए कोई Norway Problem नहीं है।
[database]
host = "localhost"
port = 5432
ssl = true
allowed_origins = [
"https://example.com",
"https://api.example.com",
]
# यह एक comment है जो बताता है कि timeout high क्यों है
timeout_ms = 30000TOML में dates और times के लिए first-class support है (publishedAt = 2026-04-04), जिन्हें JSON और YAML strings के रूप में छोड़ देते हैं जिन्हें applications खुद parse करते हैं।
Section headers ([database], [[servers]]) explicit और readable हैं। Dotted keys (database.host = "localhost") आपको nested values को inline express करने देते हैं। Array of tables ([[servers]]) आपको objects की list के लिए clean syntax देता है।
[[servers]]
name = "production"
host = "prod.example.com"
port = 443
[[servers]]
name = "staging"
host = "staging.example.com"
port = 443TOML spec precise और versioned है। प्रत्येक conformant TOML पार्सर एक ही input के लिए एक ही result produce करता है।
TOML कहां कम पड़ता है
TOML shallow-to-moderate nesting के लिए अच्छा काम करता है। Deeply nested structures के लिए — जो Kubernetes manifests या Ansible playbooks में दिखती हैं — section header syntax repetitive हो जाती है। YAML का indentation-based nesting छह या सात levels deep तक अधिक naturally scale करता है।
TOML में JSON या YAML की तुलना में कम tooling support भी है। अधिकांश भाषाओं में excellent TOML libraries हैं, लेकिन editor support (syntax highlighting, validation, autocomplete) JSON की तुलना में कम consistent है।
तुलना तालिका
निर्णय ढांचा
एक बार marketing language हटा दें, तो चुनाव तीन सवालों पर आता है।
क्या यह मुख्यतः machine-generated है या human-written?
अगर फ़ाइल code द्वारा generate होती है और code द्वारा consume होती है — एक API response, एक build artifact, एक serialized cache entry — तो JSON उपयोग करें। यह सबसे portable, सबसे parseable है, और tooling support universal है। एक ऐसी फ़ाइल में comments की ज़रूरत नहीं जिसे कोई human नहीं पढ़ता। इन JSON files को compress करना नेटवर्क पर transfer करने से पहले payload size को काफी कम कर सकता है।
अगर एक human नियमित रूप से इस फ़ाइल को लिखता और edit करता है — एक project config, एक environment description, एक tool manifest — तो comments non-negotiable हैं। यह plain JSON को नकार देता है।
क्या आप toolchain को control करते हैं?
अगर आप एक ऐसे ecosystem में बंधे हैं जो एक format mandate करता है — Kubernetes को YAML चाहिए, GitHub Actions को YAML चाहिए, Cargo को TOML चाहिए, package.json JSON है — तो कोई निर्णय नहीं लेना है। वही उपयोग करें जो ecosystem expect करता है।
अगर आप scratch से एक नया tool या नई config file design कर रहे हैं, तो आपके पास एक वास्तविक विकल्प है।
Nesting कितना deep है, और आपकी team subtle bugs के प्रति कितनी tolerant है?
YAML expressive लेकिन fragile है। एक team जो careful YAML लिखती है, सभी strings को quote करती है, एक linter चलाती है, और 1.1 बनाम 1.2 distinction समझती है, उसे safely उपयोग कर सकती है। एक team जो तेज़ी से move करती है, diverse editor setups है, और CI में YAML linting नहीं चलाती, अंततः production में Norway Problem या octal bug से टकराएगी।
TOML human-written config के लिए safer choice है जब आप format control करते हैं। Explicit types का मतलब है कि parser error parse time पर surface होती है, न कि runtime पर जब Norway false बन गई हो और आपकी feature flag logic चुपचाप fail हो रही हो।
Quick reference
- API response या services के बीच data interchange: JSON
- Package manifest (mainly machine-written): JSON
- Kubernetes, Docker Compose, GitHub Actions, Ansible: YAML (कोई विकल्प नहीं)
- नई project config file जो आप design कर रहे हैं: TOML
- Rust project: TOML (
Cargo.toml) - Python project: TOML (
pyproject.toml) - Simple key-value ज़रूरतों वाला legacy application config: INI (या TOML पर migrate करें)
अपनी Config Files को Validate करें
Config files में syntax errors diagnose करने के लिए सबसे frustrating bugs में से हैं — application start होने में fail होती है, error message cryptic होती है, और mistake एक misplaced character है।
JSON के लिए, आप JSON को online validate और pretty-print कर सकते हैं ताकि errors तुरंत पकड़ें। Commit करने से पहले JSON config file को validator में paste करने में पाँच सेकंड लगते हैं और CI failures की एक category को रोकता है। Deeper JSON workflows के लिए — production के लिए minify करना, environments के बीच config changes diff करना — हमारी गाइड देखें JSON को validate, minify और pretty-print कैसे करें।
YAML के लिए, yamllint standard CLI linter है। अगर आपकी team production YAML लिखती है तो इसे CI में चलाना optional नहीं है। TOML के लिए, अधिकांश language ecosystems एक built-in validator ship करते हैं (cargo check implicitly Cargo.toml validate करता है; python -c "import tomllib; tomllib.load(open('pyproject.toml', 'rb'))" किसी भी TOML file को directly validate करता है)।
Format एक Contract है
जो भी format आप चुनें, वह हर developer और tool के साथ एक contract बन जाता है जो आपके project को touch करता है। बाद में इसे बदलना painful है — impossible नहीं, लेकिन painful। Python ecosystem में setup.cfg और setup.py से pyproject.toml की migration में वर्षों लगे और अभी भी complete नहीं है।
सोच-समझकर चुनें। JSON जब machines primary consumer हों और portability critical हो। YAML जब ecosystem उसे mandate करे या जब deeply nested structures को readable होना हो। TOML जब humans फ़ाइल लिखें, correctness matter करे, और आप चाहते हों कि parser read time पर ambiguity catch करे बजाय इसके कि यह six months बाद runtime bug के रूप में surface हो।
Config format सिर्फ एक file format नहीं है। यह एक statement है कि फ़ाइल कौन edit करता है, कौन से tools इसे process करते हैं, और आप implicit type coercion पर कितना भरोसा करते हैं। वह statement deliberately करें।
अभी एक JSON config file validate करनी है? FileCrank JSON Viewer try करें — अपना JSON paste करें, errors तुरंत पकड़ें, और readability के लिए pretty-print करें।