Skip to content
Torna al blog
Tutorial

Guida online JSON5 e JSONC: formattazione JSON permissiva

Scopri le differenze tra JSON5 e JSONC, formatta i file di config con commenti e integra i formattatori nella pipeline CI — con esempi di codice reali.

9 min di lettura

Quando il JSON stretto ti fa fare debug fino a notte fonda per una virgola mancante, potrebbe essere il momento di incontrare i suoi cugini più permissivi — JSON5 e JSON with Comments (JSONC).

Cos’è JSON5?

JSON5 è un’estensione di JSON che incorpora funzionalità da ECMAScript 5.1, incluse chiavi senza virgolette, virgole finali, stringhe tra apici singoli, commenti e numeri esadecimali. È mantenuto dalla community e progettato per rendere i file di configurazione scritti a mano più leggibili e permissivi del JSON stretto.

Cos’è JSONC?

JSONC (JSON with Comments) è un’estensione minimale del JSON standard che aggiunge supporto per commenti su una riga (//) e su più righe (/* */). Le virgole finali, invece, non sono sempre ammesse: dipende dal parser. È il formato nativo per le impostazioni di VS Code, tsconfig.json e altri file di configurazione TypeScript.

Perché abbiamo bisogno di JSON “permissivo”

  • Colli di bottiglia di leggibilità: Il JSON standard vieta commenti, virgole finali, apici singoli, ecc., il che danneggia la chiarezza in config e demo.
  • Dolori della collaborazione di team: File JSON enormi senza note inline sono difficili da mantenere; una piccola modifica può rompere l’intero file.
  • Realtà DevOps: Kubernetes e le pipeline CI/CD spesso uniscono o generano JSON al volo; una sintassi permissiva taglia le correzioni manuali.

JSON5 vs. JSONC a colpo d’occhio

FunzionalitàJSON (RFC 8259)JSONCJSON5
Commenti // e /* */NoSìSì
Virgole finaliNoDipende dal parser (vedi sotto)Sì, una per oggetto o array
Chiavi senza virgoletteNoNoSì
Stringhe tra apici singoliNoNoSì
Stringhe su più righe (a capo con escape)NoNoSì
Numeri esadecimali (0x1F)NoNoSì
.5, 5., + inizialeNoNoSì
Infinity, NaNNoNoSì
Numeri binari (0b101)NoNoNo
SpecificaRFC 8259 / ECMA-404Nessuno standard formale; definito di fatto da VS Code e jsonc-parserSpec JSON5 1.0.0
Letto da JSON.parse / json.loads integratiSìNoNo

Fonti: la spec JSON5, la documentazione JSON di VS Code e RFC 8259. La riga sui numeri binari l’abbiamo verificata: JSON5.parse('{a: 0b101}') con json5 2.2.3 fallisce con JSON5: invalid character 'b' at 1:6.

In una frase: JSON5 sembra un letterale di oggetto JavaScript, mentre JSONC è JSON normale che tollera i commenti: chiavi e stringhe vanno comunque tra virgolette doppie.

Virgole finali in JSONC: dipende dal parser

JSONC non ha una specifica ufficiale. Microsoft lo ha introdotto in modo informale per i file di configurazione di VS Code e ha rilasciato insieme jsonc-parser. Una bozza della community su jsonc.org cerca di formalizzarlo, ma sulle virgole finali dice solo che i parser “MAY support trailing commas” (possono supportarle). E infatti gli strumenti reali si comportano in modo diverso:

Parser o strumentoVirgola finaleFonte
VS Code, modalità JSON with CommentsAccettata, con un avvisoDocumentazione di VS Code
jsonc-parser 3.3.1, opzioni predefiniteSegnalata con gli errori PropertyNameExpected / ValueExpected, ma un valore viene comunque restituitoTest più avanti
jsonc-parser 3.3.1, allowTrailingComma: trueAccettataTest più avanti
TypeScript 5.9.3 (tsc -p)AccettataTest sul tsconfig.json di esempio qui sotto
Deno (deno.jsonc)AccettataDocumentazione di configurazione di Deno

Se il file deve essere accettato da qualsiasi lettore JSONC, evita le virgole finali.

Esempi di sintassi

JSON vanilla (stretto)

{
  "name": "Go Tools",
  "features": ["Base64", "JSON Formatter"]
}

Esempio JSON5

Un file JSON5, config.json5:

// configurazione di sviluppo
{
  name: 'go-tools',
  port: 0x1F90,       // 8080 in esadecimale
  tags: ['json', 'json5',],
}

Esempio JSONC

Un file JSONC, tsconfig.json:

{
  // controllo dei tipi rigoroso
  "compilerOptions": {
    "strict": true,
    "target": "ES2022", /* output moderno */
  },
  "include": ["src"],
}

Che formato ha il tuo file?

L’estensione da sola non basta: anche un file .json può essere analizzato come JSONC o JSON5. Controlla questa tabella, poi la documentazione dello strumento che legge il file.

FileFormatoNoteFonte
tsconfig.json, jsconfig.json, tsconfig.*.jsonJSONCVS Code li apre in modalità JSONC; tsc 5.9.3 accetta commenti e virgole finaliSorgente di VS Code (typescript-basics), nostro test
.vscode/settings.json, tasks.json, launch.jsonJSONCElencati tra i file JSON with CommentsDocumentazione di VS Code
devcontainer.jsonJSONCLa spec lo definisce “a JSON with Comments file” (un file JSON con commenti)Spec Dev Container
deno.jsoncJSONC“with deno.jsonc you can add comments and trailing commas” (con deno.jsonc puoi aggiungere commenti e virgole finali)Documentazione di Deno
babel.config.json, .babelrc.jsonJSON5, nonostante l’estensione .jsonBabel li analizza come JSON5; VS Code li evidenzia come JSONCDocumentazione di Babel, sorgente di VS Code
renovate.json5, .renovaterc.json5JSON5Anche renovate.json accetta JSONCDocumentazione di Renovate
Qualsiasi file *.json5JSON5——
package.jsonJSON strettonpm: “It must be actual JSON, not just a JavaScript object literal.” (deve essere vero JSON, non un semplice letterale di oggetto JavaScript)Documentazione di npm, nostro test

Babel non cerca un file babel.config.json5: .json5 non è tra le estensioni che documenta. Sono le varianti .json quelle che legge come JSON5.

Gli errori che vedrai, parola per parola

Abbiamo passato due piccoli file a ciascun runtime. comment.json contiene un commento:

{
  // porta del server di sviluppo
  "port": 8080
}

trailing.json ha una virgola finale:

{
  "port": 8080,
}

Node.js 26.10.0, JSON.parse (Chrome Headless Shell 156 restituisce lo stesso testo, perché entrambi usano V8):

comment.json  -> SyntaxError: Expected property name or '}' in JSON at position 4 (line 2 column 3)
trailing.json -> SyntaxError: Expected double-quoted property name in JSON at position 18 (line 3 column 1)

Python 3.13.5, json.loads:

comment.json  -> json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 2 column 3 (char 4)
trailing.json -> json.decoder.JSONDecodeError: Illegal trailing comma before end of object: line 2 column 15 (char 16)

jq 1.7:

comment.json  -> jq: parse error: Invalid numeric literal at line 2, column 5
trailing.json -> jq: parse error: Expected another key-value pair at line 3, column 1

npm 11.19.1, con una riga // comment in package.json:

npm error code EJSONPARSE
npm error JSON.parse Invalid package.json: JSONParseError: Expected property name or '}' in JSON at position 4 (line 2 column 3) while parsing near "{\n  // comment\n  \"name\":..."
npm error JSON.parse Failed to parse JSON data.
npm error JSON.parse Note: package.json must be actual JSON, not just JavaScript.

Come leggerli:

  • position 4 (line 2 column 3) indica la prima / del commento. Se l’errore cade all’inizio di una riga che comincia con // o /*, il file è quasi certamente JSONC o JSON5.
  • Sulle virgole finali, V8 e Python puntano in punti diversi. V8 segnala la } di chiusura (riga 3), mentre Python 3.13.5 segnala la virgola stessa (riga 2, colonna 15). Altre versioni possono formulare i messaggi in modo diverso; il testo qui sopra è esattamente quello stampato da queste versioni.
  • Se l’errore cita un carattere che non vedi, come in Unexpected token '', "{}" is not valid JSON di Node 26 (in realtà entrambe le coppie di virgolette contengono un U+FEFF invisibile), molto probabilmente il file inizia con un byte order mark (BOM) invisibile, non con un commento. Vedi BOM UTF-8 ed errori di JSON.parse.

Conversione da JSONC o JSON5 a JSON standard

La conversione elimina tutti i commenti, perché in JSON non c’è posto per conservarli. Tieni il file commentato come sorgente e tratta l’output .json come un artefatto generato.

Node.js: da JSON5 a JSON con json5

// json5-to-json.mjs (installa con npm install json5)
import { readFileSync, writeFileSync } from 'node:fs';
import JSON5 from 'json5';

const data = JSON5.parse(readFileSync('config.json5', 'utf8'));
writeFileSync('config.json', JSON.stringify(data, null, 2) + '\n');

Eseguito con json5 2.2.3 sull’esempio JSON5 di sopra, config.json diventa:

{
  "name": "go-tools",
  "port": 8080,
  "tags": [
    "json",
    "json5"
  ]
}

Node.js: da JSONC a JSON con jsonc-parser

jsonc-parser è il parser di Microsoft per JSON con commenti. La sua parse() non lancia eccezioni sugli errori di sintassi: raccoglie i problemi in un array errors e restituisce comunque il valore migliore che riesce a ricostruire, quindi quell’array devi controllarlo tu:

// jsonc-to-json.mjs (installa con npm install jsonc-parser)
import { readFileSync } from 'node:fs';
import { parse, printParseErrorCode } from 'jsonc-parser';

const errors = [];
const data = parse(readFileSync('tsconfig.json', 'utf8'), errors, {
  allowTrailingComma: true,
});
if (errors.length > 0) {
  for (const e of errors) console.error(printParseErrorCode(e.error), 'at offset', e.offset);
  process.exit(1);
}
console.log(JSON.stringify(data, null, 2));

Con jsonc-parser 3.3.1 e l’esempio tsconfig.json di sopra, lo script stampa JSON pulito ed esce con codice 0. Senza allowTrailingComma: true, lo stesso file segnala PropertyNameExpected e ValueExpected in corrispondenza della } che segue subito ciascuna virgola finale.

Python: il pacchetto json5

Il modulo json della libreria standard non ha alcuna opzione per i commenti. Il pacchetto json5 legge JSON5, e quindi anche JSONC, dato che commenti e virgole finali sono entrambi validi in JSON5:

# installa con pip install json5
import json

import json5

with open("tsconfig.json", encoding="utf-8") as f:
    data = json5.load(f)

print(json.dumps(data, indent=2, ensure_ascii=False))

Testato con Python 3.13.5 e json5 0.17.3, stampa lo stesso JSON della versione Node.

Riga di comando: la CLI json5

Il pacchetto npm json5 include una CLI che converte in JSON e valida. Legge anche i file JSONC:

npx json5 config.json5                      # JSON compatto su stdout
npx json5 -s 2 -o config.json config.json5  # indentato, scritto su file
npx json5 -v tsconfig.json                  # solo validazione; codice di uscita 1 se trova un errore di sintassi

Poiché con -v il codice di uscita è 1 in caso di errore di sintassi, lo stesso comando funziona come step di CI che controlla i file JSON5 o JSONC modificati a mano.

jq qui non aiuta: come visto sopra, jq 1.7 si ferma al primo commento.

Attenzione a Infinity e NaN

JSON5 ammette Infinity e NaN, ma JSON non ha modo di rappresentarli, e i due linguaggi gestiscono la cosa in modo diverso:

JSON.stringify(JSON5.parse('{a: Infinity, b: NaN}'));
// '{"a":null,"b":null}'  (diventa null senza alcun avviso)
json.dumps(json5.loads('{a: Infinity, b: NaN}'))
# '{"a": Infinity, "b": NaN}'  (un output che non è JSON valido)
json.dumps(json5.loads('{a: Infinity}'), allow_nan=False)
# ValueError: Out of range float values are not JSON compliant: inf

Se un file JSON5 può contenerli, in Python passa allow_nan=False, oppure controllali prima di convertire. Quanto alle stringhe JSON5 tra apici singoli che contengono " o backslash, JSON.stringify ne rifà l’escape. Le regole sono nella guida all’escape delle stringhe JSON.

Validazione del JSON convertito

Dopo la conversione, incolla l’output nel Formattatore JSON per validarlo e formattarlo con indentazione. Funziona direttamente nel browser.

Tieni presente che il formattatore accetta solo JSON stretto. Analizza il testo con il JSON.parse del browser, quindi un file JSONC o JSON5 incollato così com’è fallisce con un errore di sintassi, che indica la riga e la colonna in cui il parsing si è fermato. Prima converti, poi valida.

Quando non usare JSONC o JSON5

  • Payload delle API e scambio di dati. RFC 8259 dice che un generatore JSON “MUST strictly conform to the JSON grammar” (deve rispettare rigorosamente la grammatica JSON). Dall’altra parte di solito c’è JSON.parse o json.loads, ed entrambi rifiutano i commenti.
  • package.json. npm richiede JSON stretto. Basta un solo commento perché comandi npm come npm run falliscano con EJSONPARSE.
  • File letti da strumenti che non controlli. require('./tsconfig.json') di Node usa il parser JSON stretto e fallisce su un tsconfig con commenti (SyntaxError: …tsconfig.json: Expected property name or '}' in JSON at position 4). Qualsiasi script che legge un file JSONC ha bisogno di un parser JSONC.
  • Un file .json diventato JSONC senza che nessuno se ne accorgesse. La documentazione di Renovate consiglia un file .jsonc invece di un .json con commenti, perché quest’ultimo “can cause issues with editors and syntax highlighting” (può creare problemi con gli editor e con l’evidenziazione della sintassi). Un’estensione esplicita dice a ogni strumento cosa aspettarsi.

Se stai scegliendo da zero un formato di configurazione e vuoi i commenti ovunque, TOML e YAML li supportano nativamente. Vedi TOML vs JSON vs YAML.

File di configurazione del mondo reale

JSON5 e JSONC sono già ampiamente usati in file di configurazione che incontri ogni giorno. Ecco esempi concreti:

TypeScript (tsconfig.json — JSONC)

{
  // La modalità strict cattura più bug a tempo di compilazione
  "compilerOptions": {
    "strict": true,
    "target": "ES2022",
    "module": "ESNext",
    "outDir": "./dist",
    // Alias di percorso per import più puliti
    "paths": {
      "@/*": ["./src/*"],
      "@tests/*": ["./tests/*"],
    },
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"],
}

tsconfig.json di TypeScript usa JSONC nativamente — commenti e virgole finali funzionano fuori dalla scatola. È uno dei file JSONC più comuni in qualsiasi progetto JavaScript/TypeScript.

Babel (babel.config.json — JSON5)

Babel analizza babel.config.json e .babelrc.json come JSON5, quindi lì funzionano anche chiavi senza virgolette e apici singoli.

{
  // Apici singoli e chiavi senza virgolette lo rendono più leggibile
  presets: [
    ['@babel/preset-env', {
      targets: '> 0.25%, not dead',
      modules: false,  // Lascia che il bundler gestisca i moduli
    }],
  ],
  plugins: [
    '@babel/plugin-transform-runtime',
  ],
}

Impostazioni workspace di VS Code (.vscode/settings.json — JSONC)

{
  // Preferenze editor
  "editor.fontSize": 14,
  "editor.tabSize": 2,
  "editor.formatOnSave": true,

  // Override specifici per linguaggio
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode",
  },
}

Suggerimenti pratici e avvertenze

1. Converti prima della produzione

Il JSON.parse dei browser accetta solo JSON stretto. Converti i file in fase di build, come mostrato nella sezione sulla conversione qui sopra.

2. Sicurezza e affidabilità

La permissività può nascondere campi indesiderati. Valida sempre la configurazione con JSON Schema o zod prima di consumarla:

// Valida la forma della config con zod dopo il parsing
import { readFileSync } from 'node:fs';
import { z } from 'zod';
import JSON5 from 'json5';

const ConfigSchema = z.object({
  port: z.number().min(1).max(65535),
  host: z.string(),
  debug: z.boolean().default(false),
});

const raw = JSON5.parse(readFileSync('config.json5', 'utf8'));
const config = ConfigSchema.parse(raw); // Lancia se non valido

3. Convenzioni di team

  • Dichiara nel README che *.json5 è solo per le config; i pacchetti rilasciati dovrebbero spedire .json stretto.
  • Standardizza le regole di Prettier per evitare diff rumorosi.
  • Usa .editorconfig per imporre indentazione coerente tra file JSON, JSON5 e JSONC.

4. Prestazioni

Analizzare JSON5/JSONC aggiunge dipendenze e leggero overhead — va bene per CLI e dev tooling, ma misura per la produzione. Per file di configurazione caricati una volta all’avvio, è trascurabile. Per percorsi caldi che analizzano migliaia di oggetti al secondo, attieniti al JSON stretto.

Domande frequenti

Qual è la differenza tra JSON5 e JSONC?

JSONC è JSON standard più i commenti // e /* */; il supporto per le virgole finali dipende dal parser. JSON5 va oltre con la sintassi di ES5.1: chiavi senza virgolette, apici singoli, numeri esadecimali, Infinity/NaN e virgole finali. Un file JSONC valido di solito è anche JSON5 valido, ma non vale il contrario. Scegli JSONC per file di config dove i commenti bastano; scegli JSON5 quando hai bisogno di sintassi più ricca.

Posso usare JSON5 o JSONC nelle API di produzione?

No — JSON5 e JSONC sono progettati per file di configurazione, non per scambio dati. Le API dovrebbero usare JSON standard (RFC 8259) per la massima interoperabilità. Riserva JSON5/JSONC per file di config locali come tsconfig.json, .vscode/settings.json o configurazione di ambiente dove la leggibilità umana conta più del parsing macchina.

VS Code supporta JSON5 nativamente?

Non di serie. L’estensione JSON integrata in VS Code registra linguaggi come json, jsonc e jsonl, ma non json5, quindi per avere l’evidenziazione della sintassi nei file .json5 serve un’estensione del marketplace. JSONC invece è integrato: le impostazioni, tasks.json, launch.json e tsconfig.json si aprono tutti in modalità JSON with Comments.

Come converto JSON5 in JSON standard?

Usa il pacchetto npm json5: JSON5.parse() legge JSON5, poi JSON.stringify() produce JSON standard. Per uso CLI, esegui npx json5 < input.json5 > output.json. I commenti vengono eliminati, e JSON.stringify trasforma Infinity e NaN in null. Strumenti online come il nostro JSON Formatter possono anche validare l’output convertito per assicurare la correttezza.

JSONC è la stessa cosa di JSON con commenti?

Sì — “JSON with Comments” è il nome della modalità linguaggio di VS Code, e jsonc è il suo ID di linguaggio e la sua estensione di file. Non esiste uno standard formale: su jsonc.org c’è una bozza della community, basata su ciò che jsonc-parser accetta con le opzioni predefinite. Al JSON standard aggiunge i commenti // e /* */, mentre il supporto per le virgole finali dipende dal parser. I parser rimuovono i commenti prima dell’elaborazione, quindi la struttura dati risultante è identica al JSON standard.

Per più strumenti per sviluppatori basati su browser inclusi codifica Base64, generazione di hash e conversione di timestamp, vedi la nostra Guida agli strumenti essenziali per sviluppatori.

Bilanciare leggibilità e rigore è una classica lotta degli sviluppatori. JSON5 e JSONC migliorano l’esperienza di scrittura, e con la giusta pipeline di build e validazione, puoi godere dei vantaggi del “JSON permissivo” in sicurezza.

Riferimenti

Tag: json json5 jsonc formatting developer-tools

Articoli correlati

Vedi tutti gli articoli