JSON5 und JSONC: JSON mit Kommentaren
Fazit: Beide Dialekte existieren, weil von Menschen geschriebene Konfigurationen Kommentare und nachfolgende Kommas brauchen, doch Syntax und Reichweite im Ökosystem unterscheiden sich – eine falsche Wahl blockiert Ihre Toolchain.

Kurz gesagt: Verwenden Sie JSONC für Kommentare in VS-Code- und TypeScript-Konfigurationen, JSON5, wenn Sie die breitere ES5.1-Literal-Syntax wie einfache Anführungszeichen oder unquotierte Schlüssel brauchen, und halten Sie öffentliche APIs bei Standard-JSON.
Standard-JSON erlaubt keine Kommentare, also schreibt sie jedes Team heimlich trotzdem – bis eines Tages der Build bricht. Statt es heimlich zu tun, wählen Sie einen ordentlichen Dialekt.
1. Die beiden Dialekte haben unterschiedliche Motive
- JSONC (JSON with Comments): Standard-JSON plus Kommentare und nachfolgende Kommas, mit fast keinen anderen Syntaxänderungen. Es ist der De-facto-Standard des VS-Code-Ökosystems –
settings.json,tsconfig.jsonund.eslintrc.jsonverwenden es alle. - JSON5: weit ehrgeiziger und direkt am ES5.1-Objektliteral ausgerichtet – einfache Anführungszeichen, unquotierte Schlüssel, Hexadezimal,
Infinity/NaN, Backslash-Zeilenfortsetzung und führende+-Zeichen.
Ein Satz zur Unterscheidung: JSONC macht nur das Schreiben bequem; JSON5 lässt Sie eine Konfigurationsdatei schreiben, als wäre sie JavaScript.
2. Syntaxvergleichstabelle
| Merkmal | Standard-JSON | JSONC | JSON5 |
|---|---|---|---|
Kommentare // /* */ |
✗ | ✓ | ✓ |
| Nachfolgende Kommas | ✗ | ✓ | ✓ |
| Einfach quotierte Strings | ✗ | ✗ | ✓ |
| Unquotierte Schlüssel | ✗ | ✗ | ✓ |
| Hexadezimale Zahlen | ✗ | ✗ | ✓ |
Führender/nachfolgender Dezimalpunkt .5 5. |
✗ | ✗ | ✓ |
Zahlen mit + am Anfang |
✗ | ✗ | ✓ |
Infinity / NaN |
✗ | ✗ | ✓ |
Zeilenfortsetzung mit \ am Zeilenende |
✗ | ✗ | ✓ |
| Mehrzeilige Strings | ✗ | ✗ | ✓ (über Zeilenfortsetzung umgesetzt) |
| Beliebiger oberster Wert | ✓ | ✓ | ✓ |
Die vollständige JSON5-Spezifikation umfasst kaum mehr als eine Seite; das json5-Paket wird seit langem von der Community gepflegt, und Browser und Node verhalten sich identisch.
3. Parsen: zwei APIs, zwei Arten von Positionierungsfähigkeit
3.1 JSON5: einfaches Parsen des ganzen Dokuments
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 liefert ein einfaches Objekt ohne Offset-Informationen – weil es nicht auf Bearbeitungsszenarien zielt, sondern nur auf „Konfiguration lesen“.
3.2 JSONC: ein Syntaxbaum mit Offsets
Der Wert von jsonc-parser liegt nicht im Parsen, sondern im Bearbeiten. Es bietet drei API-Ebenen:
| API | Zweck | Typische Verwendung |
|---|---|---|
parse |
In einen Baum mit offset/length parsen |
Syntaxhervorhebung, Folding, Navigation |
visit |
Tiefensuche; der Callback erhält den Knotenpfad | JSONPath-ähnliche Inspektion |
modify + applyEdits |
Eine minimale Textänderung erzeugen und auf den Originaltext anwenden | Einen Wert ändern und Kommentare behalten |
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));
Die Ausgabe behält die ursprünglichen Kommentare und ersetzt nur die drei Zeichen von 8080:
{
// port configuration
"server": {
"port": 3000 // 80 in production
}
}
Genau das kann „Konfiguration mit regulären Ausdrücken bearbeiten“ nicht: Ein Regex weiß nicht, welches 8080 zu ändern ist, und weiß nicht, dass das 8080 innerhalb eines Strings unangetastet bleiben muss.
3.3 Fehlermeldungen müssen Offsets mitführen
Die Fehlercodes von jsonc-parser sind Enum-Werte; die häufigen sind:
| Fehlercode | Bedeutung |
|---|---|
InvalidSymbol |
Ein Zeichen erschien, das dort nicht hingehört |
PropertyNameExpected |
Ein Schlüsselname wurde erwartet |
ColonExpected |
Ein Doppelpunkt wurde erwartet |
CommaExpected |
Ein Komma wurde erwartet |
CloseBraceExpected |
Das Objekt wurde nicht geschlossen |
UnexpectedEndOfComment |
Der Kommentar wurde nicht geschlossen |
InvalidEscapeCharacter |
Ungültiges Escape |
Sobald offset in Zeile und Spalte umgerechnet ist, kann der Editor die Wellenlinie genau auf die fehlerhafte Stelle zeichnen.
4. Wann welches Format
| Szenario | Empfehlung | Grund |
|---|---|---|
| Request-/Response-Bodies öffentlicher APIs | Standard-JSON | Dialekte werden von universellen Clients nicht unterstützt |
package.json, composer.json |
Standard-JSON | Paketmanager verstehen nur Standard-JSON |
tsconfig.json, .vscode/settings.json |
JSONC | Der Ökosystem-Standard, von der Toolchain nativ unterstützt |
| Anwendungskonfiguration (benötigt Kommentare) | JSONC oder YAML | Kommentare müssen erhalten bleiben, während Werkzeuge sie noch lesen und schreiben können |
Benötigt Infinity, Hexadezimal, komplexe Literale |
JSON5 | Die stärkste Ausdruckskraft |
| Datenaustausch, Logs, Caches | Zeilengetrennt oder Standard-JSON | Streaming und Universalität sind erforderlich |
Faustregel: Wird die Datei von einem „nicht-menschlichen Werkzeug“ gelesen, bevorzugen Sie Standard-JSON; erwägen Sie einen Dialekt nur, wenn Sie sicher sind, dass ausschließlich Ihr eigener Code sie liest.
5. Drei Risiken, die Dialekte mitbringen
5.1 Ausufernde Anforderung
Wenn ein anderes Werkzeug eine JSON5-Konfigurationsdatei liest und JSON.parse aufruft, stürzt es schlicht ab. Das typische Symptom ist „lokal läuft es, in Docker nicht“ – weil der Container einen anderen Lesepfad ausführt.
Gegenmaßnahme: Im Repository eine CI-Prüfung ergänzen, die ausdrücklich auflistet, welche Dateien einen Dialekt verwenden dürfen; alles andere wird als Standard-JSON validiert.
5.2 Überraschungen bei der Typinferenz
JSON5 erlaubt unquotierte Schlüssel und einfache Anführungszeichen, aber es erlaubt nicht, literale Konstrukte wie Daten oder reguläre Ausdrücke einzubringen – es bleibt ein Datenformat, keine JavaScript-Auswertung.
Manche haben angenommen, JSON5 könne new Date() ausdrücken, und dann scheiterte das Parsen. JSON5 ist kein eval.
5.3 Kommentare verschwinden stillschweigend
Weder JSON5.stringify noch JSON.stringify bewahren Kommentare. Also verliert „einlesen, einen Wert anpassen, zurückschreiben“ jeden Kommentar.
Müssen Kommentare überleben, bleiben nur die Bearbeitungs-API von jsonc-parser oder eine YAML-Bibliothek mit Kommentarerhaltung.
6. Praktische Empfehlungen
- [ ] In der Teamdokumentation eine Tabelle „Dateityp → Format“ führen, damit niemand improvisiert;
- [ ] Das Lesen von Konfiguration in ein einzelnes
loadConfig()kapseln, das intern entscheidet, welcher Parser verwendet wird, sodass Geschäftscode nie direktJSON.parseaufruft; - [ ] Beim programmatischen Ändern einer Konfiguration mit Kommentaren
modify+applyEditsverwenden; niemals die ganze Datei neu schreiben; - [ ] Dialektdateien ebenfalls in CI validieren (
jsonc-parserfür JSONC,JSON5.parsefür JSON5), sonst zeigen sich Syntaxfehler erst zur Laufzeit; - [ ] Für öffentliche Schnittstellen, Cache-Schlüssel und Message-Queue-Payloads Standard-JSON verwenden.
FAQ
Wie soll ich zwischen JSON5 und JSONC wählen?
Wählen Sie nach Laufzeitumgebung, nicht nach der Zahl der Syntaxfeatures: VS Code, TypeScript und ESLint lesen standardmäßig JSONC, deshalb bietet JSONC die beste Kompatibilität; greifen Sie nur dann zu JSON5, wenn Sie die breitere ES5.1-Literal-Syntax wie einfache Anführungszeichen, unquotierte Schlüssel oder Infinity brauchen. Keiner der beiden Dialekte eignet sich für öffentliche API-Antworten.
Warum kann ein Standard-JSON-Parser JSONC nicht direkt lesen?
JSONC erlaubt Kommentare und nachfolgende Kommas, während JSON.parse nur RFC-8259-JSON akzeptiert und bei beidem wirft. JSONC zu lesen erfordert einen Parser wie jsonc-parser oder das Entfernen der Kommentare, bevor der Text einem Standardparser übergeben wird.
Sollten Kommentare in JSONC Bearbeitungen der Datei überleben?
Ja, aber nur über eine Bearbeitungs-API. modify und applyEdits von jsonc-parser ändern den Zielknoten und bewahren die übrigen Kommentare; das Parsen in ein Objekt und erneute Stringifizieren verwirft jeden Kommentar.