JSON5 और JSONC: comments वाला JSON
मुख्य बात: दोनों dialects इसलिए हैं क्योंकि मनुष्यों द्वारा लिखी config को comments और trailing commas चाहिए, पर उनका syntax और पारिस्थितिकी तंत्र अलग है, इसलिए गलत चुनाव आपकी toolchain को फँसा देता है।

सार: VS Code और TypeScript configuration के भीतर comments के लिए JSONC इस्तेमाल करें, जब single quotes या unquoted keys जैसे व्यापक ES5.1 literal syntax चाहिए तो JSON5, और public APIs को मानक JSON पर रखें।
मानक JSON comments की अनुमति नहीं देता, इसलिए हर टीम चुपचाप उन्हें फिर भी लिखती है — जब तक एक दिन build न टूटे। चोरी-छिपे करने के बजाय एक उचित dialect चुनें।
1. दोनों dialects की प्रेरणाएँ अलग हैं
- JSONC (JSON with Comments): मानक JSON + comments + trailing commas, बिना लगभग किसी अन्य syntax बदलाव के। यह VS Code पारिस्थितिकी तंत्र का de facto मानक है —
settings.json,tsconfig.jsonऔर.eslintrc.jsonसब इसे इस्तेमाल करते हैं। - JSON5: कहीं अधिक महत्वाकांक्षी, सीधे ES5.1 object literal के साथ संरेखित — single quotes, unquoted keys, hexadecimal,
Infinity/NaN, backslash line continuation, और शुरुआत में+चिह्न।
अंतर बताने का एक वाक्य: JSONC लिखना बस सुविधाजनक बनाता है; JSON5 आपको configuration फ़ाइल ऐसे लिखने देता है जैसे वह JavaScript हो।
2. Syntax तुलना तालिका
| विशेषता | मानक JSON | JSONC | JSON5 |
|---|---|---|---|
Comments // /* */ |
✗ | ✓ | ✓ |
| Trailing commas | ✗ | ✓ | ✓ |
| Single-quoted strings | ✗ | ✗ | ✓ |
| Unquoted keys | ✗ | ✗ | ✓ |
| Hexadecimal numbers | ✗ | ✗ | ✓ |
Leading/trailing decimal point .5 5. |
✗ | ✗ | ✓ |
Numbers starting with + |
✗ | ✗ | ✓ |
Infinity / NaN |
✗ | ✗ | ✓ |
End-of-line \ continuation |
✗ | ✗ | ✓ |
| Multi-line strings | ✗ | ✗ | ✓ (continuation के माध्यम से लागू) |
| Arbitrary top-level value | ✓ | ✓ | ✓ |
पूरी JSON5 specification एक पृष्ठ से बमुश्किल अधिक है; json5 package लंबे समय से समुदाय द्वारा बनाए रखा गया है, और browsers व Node एक जैसा व्यवहार करते हैं।
3. Parsing: दो APIs, दो तरह की positioning क्षमता
3.1 JSON5: सरल whole-document parsing
import JSON5 from 'json5';
const config = JSON5.parse(`
{
// service port
port: 8080,
host: '0.0.0.0',
features: ['json5', 'jsonc',],
retries: 0x10,
}
`);
console.log(config.port, config.retries); // 8080 16
JSON5.parse बिना offset जानकारी के सादा object लौटाता है — क्योंकि वह संपादन परिदृश्यों के लिए नहीं, केवल "configuration पढ़ने" के लिए है।
3.2 JSONC: offsets वाला syntax tree
jsonc-parser का मूल्य parsing में नहीं, editing में है। यह तीन परतों का API देता है:
| API | उद्देश्य | सामान्य उपयोग |
|---|---|---|
parse |
offset/length रखने वाले tree में parse |
Syntax highlighting, folding, navigation |
visit |
Depth-first traversal; callback को node path मिलता है | JSONPath-जैसी जाँच |
modify + applyEdits |
न्यूनतम text edit बनाएँ, फिर मूल text पर लागू करें | Comments रखते हुए कोई मान बदलें |
import { parseTree, findNodeAtLocation, modify, applyEdits } from 'jsonc-parser';
const text = `{
// port configuration
"server": {
"port": 8080 // 80 in production
}
}`;
const tree = parseTree(text);
const portNode = findNodeAtLocation(tree!, ['server', 'port']);
console.log(portNode?.offset, portNode?.length);
const edits = modify(text, ['server', 'port'], 3000, {
formattingOptions: { insertSpaces: true, tabSize: 2 },
});
console.log(applyEdits(text, edits));
आउटपुट मूल comments रखता है और केवल 8080 के तीन characters बदलता है:
{
// port configuration
"server": {
"port": 3000 // 80 in production
}
}
यही वह चीज़ है जो "regular expressions से configuration संपादित करना" नहीं कर सकता: regex को नहीं पता कौन-सा 8080 बदलना है, और नहीं पता कि string के अंदर का 8080 छोड़ना है।
3.3 Error संदेशों में offsets होने चाहिए
jsonc-parser के error codes enum मान हैं; सामान्य वाले:
| Error code | अर्थ |
|---|---|
InvalidSymbol |
ऐसा character आया जो नहीं होना चाहिए था |
PropertyNameExpected |
Key नाम अपेक्षित था |
ColonExpected |
Colon अपेक्षित था |
CommaExpected |
Comma अपेक्षित था |
CloseBraceExpected |
Object बंद नहीं हुआ |
UnexpectedEndOfComment |
Comment बंद नहीं हुआ |
InvalidEscapeCharacter |
अवैध escape |
एक बार offset को line और column में बदल दिया जाए, तो एडिटर squiggle ठीक दोषी स्थिति पर खींच सकता है।
4. कब कौन-सा इस्तेमाल करें
| परिदृश्य | सुझाव | कारण |
|---|---|---|
| Public API request/response bodies | मानक JSON | सामान्य-प्रयोजन clients dialects समर्थित नहीं करते |
package.json, composer.json |
मानक JSON | Package managers केवल मानक JSON समझते हैं |
tsconfig.json, .vscode/settings.json |
JSONC | पारिस्थितिकी तंत्र का डिफ़ॉल्ट, toolchain द्वारा मूल समर्थन |
| Application configuration (comments चाहिए) | JSONC या YAML | Comments सुरक्षित रहें जबकि उपकरण अब भी पढ़-लिख सकें |
Infinity, hexadecimal, जटिल literals चाहिए |
JSON5 | सबसे मज़बूत expressive power |
| डेटा आदान-प्रदान, logs, caches | Line-delimited या मानक JSON | Streaming और सार्वभौमिकता ज़रूरी |
सामान्य नियम: अगर फ़ाइल को कोई "गैर-मानव उपकरण" पढ़ेगा, तो मानक JSON पसंद करें; dialect पर तभी विचार करें जब आप निश्चित हों कि इसे केवल आपका अपना code पढ़ता है।
5. Dialects जो तीन तरह के जोखिम लाते हैं
5.1 ज़रूरत का spillover
जब कोई अन्य उपकरण JSON5 configuration फ़ाइल पढ़कर JSON.parse बुलाता है, तो वह सीधे crash हो जाता है। आम लक्षण है "locally ठीक चलता है, Docker पर fail" — क्योंकि container अलग reading path चलाता है।
उपाय: repository में CI जाँच जोड़ें जो स्पष्ट रूप से सूचीबद्ध करे कि किन फ़ाइलों को dialect इस्तेमाल करने की अनुमति है; बाकी सब मानक JSON के रूप में validate हों।
5.2 Type inference के आसपास आश्चर्य
JSON5 unquoted keys और single quotes की अनुमति देता है, पर यह dates या regular expressions जैसे literal constructs नहीं ला सकता — यह अब भी data format है, JavaScript evaluation नहीं।
लोगों ने मान लिया कि JSON5 new Date() व्यक्त कर सकता है, फिर parse fail होते देखा। JSON5 eval नहीं है।
5.3 Comments चुपचाप गिर जाते हैं
JSON5.stringify और JSON.stringify दोनों comments सुरक्षित नहीं रखते। इसलिए "पढ़ो, मान बदलो, वापस लिखो" हर comment खो देता है।
जब comments बचे रहने ही चाहिए, तो एकमात्र विकल्प jsonc-parser का editing API है, या comment preservation समर्थित करने वाली YAML लाइब्रेरी।
6. व्यावहारिक सिफ़ारिशें
- [ ] टीम documentation में "फ़ाइल प्रकार → format" तालिका रखें ताकि कोई मनमानी न करे;
- [ ] Configuration reading को एक
loadConfig()में लपेटें जो भीतर तय करे कौन-सा parser इस्तेमाल करना है, ताकि business code सीधेJSON.parseकभी न बुलाए; - [ ] Comments वाली configuration को प्रोग्रामेटिक रूप से बदलते समय
modify+applyEditsइस्तेमाल करें; पूरी फ़ाइल कभी rewrite न करें; - [ ] Dialect फ़ाइलें CI में भी validate करें (JSONC के लिए
jsonc-parser, JSON5 के लिएJSON5.parse), वरना syntax errors केवल runtime पर सामने आएँगी; - [ ] Public interfaces, cache keys और message-queue payloads के लिए मानक JSON इस्तेमाल करें।
सामान्य प्रश्न
JSON5 और JSONC में कैसे चुनें?
Syntax की गिनती से नहीं, runtime से चुनें: VS Code, TypeScript और ESLint डिफ़ॉल्ट रूप से JSONC पढ़ते हैं, इसलिए JSONC सबसे अच्छी compatibility देता है; JSON5 तभी लें जब व्यापक ES5.1 literal syntax चाहिए, जैसे single quotes, unquoted keys या Infinity। कोई भी dialect public API responses के लिए उपयुक्त नहीं।
मानक JSON parser JSONC सीधे क्यों नहीं पढ़ सकता?
JSONC comments और trailing commas की अनुमति देता है, जबकि JSON.parse केवल RFC 8259 JSON स्वीकार करता है और दोनों पर throw करता है। JSONC पढ़ने के लिए jsonc-parser जैसा parser चाहिए, या text मानक parser को देने से पहले comments हटाने पड़ते हैं।
क्या JSONC के comments फ़ाइल में बदलाव के बाद बचे रहने चाहिए?
हाँ, पर केवल editing API से। jsonc-parser के modify और applyEdits लक्षित node बदलते हैं जबकि बाकी comments सुरक्षित रखते हैं; object में parse करके stringify करने से हर comment गिर जाता है।