JSON Toolkit

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.

Einsteiger~10 Min. LesezeitVeröffentlicht 2026-10-30Aktualisiert 2026-10-30
Titelbild für JSON5 und JSONC, JSON mit Kommentaren

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.json und .eslintrc.json verwenden 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 direkt JSON.parse aufruft;
  • [ ] Beim programmatischen Ändern einer Konfiguration mit Kommentaren modify + applyEdits verwenden; niemals die ganze Datei neu schreiben;
  • [ ] Dialektdateien ebenfalls in CI validieren (jsonc-parser für JSONC, JSON5.parse fü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.