Cos'è Babel e serve ancora nel 2026
Cos'è Babel e come funziona: preset, plugin, la differenza tra sintassi e polyfill, Browserslist, e la risposta onesta se serve ancora oggi nel 2026.
Apri un progetto di qualche anno fa e trovi un .babelrc che nessuno ricorda di aver scritto. Apri un progetto nuovo con Vite e Babel non c'è più. Nel mezzo c'è una domanda legittima: quello strumento serve ancora a qualcosa o è roba da archeologia? In questo articolo trovi cosa fa Babel esattamente, la distinzione tra sintassi e polyfill che confonde tutti, e una risposta articolata alla domanda del titolo.
Cos'è
Babel è un compilatore che prende JavaScript scritto con sintassi moderna e lo riscrive in JavaScript equivalente che i browser più vecchi sanno eseguire.
In gergo si chiama transpiler: non traduce da un linguaggio a un altro, ma da una versione dello stesso linguaggio a un'altra.
Il problema che ha risolto
Nel 2015 JavaScript ricevette l'aggiornamento più grosso della sua storia: ES2015 portò let e const, le funzioni freccia, le classi, i template literal, la destrutturazione, i moduli.
Il problema è che le specifiche escono in un giorno e i browser le implementano negli anni successivi. E anche quando le implementano, resta il pubblico che non aggiorna: nel 2016, Internet Explorer 11 era ancora una quota di traffico che nessun'azienda poteva ignorare.
Lo stallo era quello classico: nessuno usa le funzionalità nuove perché non sono supportate, e nessuno ha fretta di supportarle perché nessuno le usa.
Babel lo ha spezzato spostando il problema in fase di build. Scrivi come se tutti i browser fossero aggiornati, Babel produce la versione compatibile, e chi ha un browser vecchio vede comunque un sito funzionante.
// Quello che scrivi
const saluta = (nome) => `Ciao, ${nome}`;
// Quello che Babel produce per un browser vecchio
var saluta = function saluta(nome) {
return "Ciao, " + nome;
};
È difficile sopravvalutare quanto questo abbia accelerato il linguaggio. Da allora JavaScript riceve aggiornamenti ogni anno e la gente li adotta subito, perché il rischio di compatibilità l'ha assorbito la fase di build.
Come funziona: preset e plugin
Babel di per sé non trasforma niente. È un'infrastruttura che legge il codice, lo trasforma in un albero sintattico, lascia che dei plugin lo modifichino e poi lo riscrive. Tutte le trasformazioni vengono dai plugin.
Un plugin fa una cosa sola: trasformare le funzioni freccia, o le classi, o l'operatore di concatenamento opzionale. Configurarli uno per uno sarebbe assurdo, e per questo esistono i preset: raccolte di plugin già assemblate.
{
"presets": [
["@babel/preset-env", { "targets": "> 0.5%, not dead" }],
"@babel/preset-react",
"@babel/preset-typescript"
]
}
| Preset | A cosa serve |
|---|---|
preset-env | Il principale: sceglie da solo le trasformazioni in base ai browser che vuoi supportare |
preset-react | Converte il JSX in chiamate a funzione |
preset-typescript | Rimuove le annotazioni di tipo (senza controllarle) |
preset-env è quello che conta, e la sua intelligenza sta nel non applicare tutto sempre: legge quali browser devi supportare e include solo le trasformazioni necessarie. Se ti bastano i browser degli ultimi due anni, le funzioni freccia le lascia stare — riscriverle produrrebbe solo codice più grosso.
Su preset-typescript c'è un equivoco da chiarire: Babel cancella i tipi, non li verifica. Si limita a togliere le annotazioni, e il controllo lo fa tsc --noEmit a parte. Se ti aspettavi che una build Babel ti segnalasse un errore di tipo, è per questo che non succede. Il tema è in cos'è TypeScript.
Sintassi e polyfill: due cose diverse
Questa distinzione è la fonte numero uno di errori, e produce il bug più frustrante che esista: il codice compila senza un avviso e poi esplode sul browser dell'utente.
La sintassi è la grammatica del linguaggio. Una funzione freccia, una classe, const, async/await, il concatenamento opzionale ?.. Se un browser non conosce una sintassi, non riesce nemmeno a leggere il file: dà un errore e non esegue niente.
Le API sono i metodi e gli oggetti disponibili. Array.prototype.includes, Object.entries, Promise, Map, fetch. Sono funzioni che esistono o non esistono nel motore.
Babel trasforma solo la sintassi. Non può fare altro: riscrive codice, non aggiunge funzionalità mancanti.
// Sintassi moderna: Babel la riscrive
const trovati = lista.filter((x) => x.attivo);
// API moderna: Babel la lascia esattamente com'è
const presente = lista.includes("mela");
Quella seconda riga passa la build senza una parola. Su un browser che non ha Array.prototype.includes produce TypeError: lista.includes is not a function, in produzione, sul dispositivo del cliente.
Per le API servono i polyfill: pezzi di codice che controllano se una funzionalità esiste e, se manca, la implementano.
// Un polyfill, semplificato all'osso
if (!Array.prototype.includes) {
Array.prototype.includes = function (elemento) {
return this.indexOf(elemento) !== -1;
};
}
La libreria di riferimento è core-js, e Babel la integra. Il modo consigliato è useBuiltIns: "usage", che analizza il codice e importa solo i polyfill effettivamente serviti dai browser dichiarati:
{
"presets": [
["@babel/preset-env", {
"useBuiltIns": "usage",
"corejs": 3
}]
]
}
L'alternativa "entry" importa tutto ciò che serve al target, indipendentemente dall'uso: più sicuro, molto più pesante. E l'impostazione predefinita, false, non importa niente — è quella con cui molti compilano felicemente codice che si romperà.
In una riga: Babel fa in modo che il browser sappia leggere il tuo codice, i polyfill fanno in modo che sappia eseguirlo.
Browserslist: chi decide il target
Babel non sceglie da solo quanto essere aggressivo: glielo dici tu, con una sintassi condivisa da tutto l'ecosistema frontend. Di solito sta nel package.json:
{
"browserslist": ["> 0.5%", "last 2 versions", "not dead"]
}
Si legge: i browser con più dello 0,5% di quota, le ultime due versioni di ciascuno, escludendo quelli non più mantenuti.
È il singolo valore che influenza di più il peso della build. Aggiungi un browser di dieci anni fa e il pacchetto può gonfiarsi in modo significativo, perché rientrano decine di trasformazioni e di polyfill che servono a una manciata di visitatori.
Vale la pena controllare cosa stai chiedendo davvero:
npx browserslist
E decidere guardando i dati di chi visita il tuo sito, non per prudenza generica. Il tema del peso finale è lo stesso di cos'è un bundler.
Cosa fa perdere ore
Dimenticare i polyfill. Il caso sopra. Se supporti browser vecchi, useBuiltIns va impostato e va provato su un browser vero, non solo su quello che hai aperto.
Credere che Babel controlli i tipi. Non lo fa. Serve tsc in parallelo, o in CI come passaggio separato.
Escludere node_modules dalla transpilazione. È l'impostazione predefinita di quasi tutte le configurazioni ed è giusta nel 99% dei casi, finché non installi una libreria pubblicata con sintassi moderna. Allora la build passa e il browser vecchio si ferma su un file che non hai scritto tu.
Target troppo prudenti. "ie 11" o "> 0.1%" lasciati lì per inerzia: stai spedendo a tutti un pacchetto pensato per un pubblico che non hai più.
Doppia transpilazione. Babel dentro un bundler che già transpila con esbuild o SWC. Non rompe niente, ma raddoppia il tempo di build per nulla.
Aspettarsi che browserslist cambi le API. Dichiarare un target moderno riduce le trasformazioni di sintassi, ma se in useBuiltIns hai "entry" i polyfill continuano ad arrivare. Sono due assi separati.
Serve ancora nel 2026?
La domanda del titolo, e la risposta onesta è: non nel ruolo che aveva, ma non è affatto morto.
Le tre cose che gli hanno tolto il ruolo di protagonista:
1. I browser hanno recuperato. Internet Explorer è uscito di scena, tutti i motori attuali si aggiornano automaticamente e supportano essenzialmente tutto ES2020 e oltre. Per la grande maggioranza dei progetti pubblici, la quota di visitatori che ha bisogno di sintassi trasformata è statisticamente irrilevante. Il vantaggio principale di Babel era risolvere un problema che oggi, per molti, non esiste più.
2. esbuild e SWC fanno la stessa cosa molto più in fretta. Babel è scritto in JavaScript e gira su Node.js. esbuild è scritto in Go, SWC in Rust, entrambi parallelizzano: sulla stessa trasformazione sono uno o due ordini di grandezza più rapidi. Su un progetto medio significa passare da decine di secondi a meno di uno. È per questo che Vite usa esbuild e che Next.js ha sostituito Babel con SWC nel percorso predefinito.
3. Lo strumento è diventato invisibile. Se oggi crei un progetto con Vite, Next.js o SvelteKit, il transpiler c'è ed è già configurato bene. Non scrivi un .babelrc, non scegli i preset, e in molti casi non è nemmeno Babel.
Le tre cose per cui resta insostituibile:
1. Le trasformazioni personalizzate. Qui non ha rivali. L'ecosistema di plugin è enorme e maturo, e l'API per scriverne uno tuo è documentata e stabile. Se devi togliere automaticamente le chiamate a console.log in produzione, riscrivere gli import di una libreria per migliorare il tree shaking o implementare una macro a tempo di compilazione, Babel è lo strumento. esbuild e SWC hanno sistemi di plugin molto più limitati.
2. I browser vecchi veri. Esistono contesti in cui non puoi scegliere il pubblico: applicazioni per la pubblica amministrazione, gestionali su postazioni con browser bloccati, mercati dove i dispositivi vecchi sono la norma. Lì preset-env con core-js resta la soluzione più collaudata che esista.
3. Gli strumenti che lo usano internamente. Jest, alcune configurazioni React Native, molte librerie in fase di pubblicazione: Babel è un pezzo di infrastruttura, e continua a girare anche dove nessuno lo nomina.
Il verdetto pratico, caso per caso:
| Situazione | Ti serve Babel? |
|---|---|
| Progetto nuovo con Vite, Next.js o SvelteKit | No, il toolchain fa già tutto |
| Devi supportare browser di più di 5 anni fa | Sì, con preset-env e core-js |
| Ti serve una trasformazione su misura o una macro | Sì, non c'è alternativa reale |
| Progetto esistente con Webpack e Babel che funziona | Lascialo stare, o valuta SWC per la velocità |
| Pubblichi una libreria su npm | Probabile, per produrre più formati |
Babel non è stato superato: ha cambiato mestiere. Da strumento che ogni progetto frontend doveva avere è diventato uno strumento specialistico, che si tira fuori quando serve una cosa che gli altri non sanno fare. È una traiettoria normale per il software di successo — smette di essere una decisione e diventa un'infrastruttura.
In sintesi
Babel riscrive la sintassi moderna in sintassi che i browser vecchi capiscono. È lo strumento che ha reso adottabile JavaScript moderno mentre i browser rincorrevano.
Le trasformazioni vengono dai plugin, raccolti nei preset, e preset-env sceglie da solo cosa applicare in base al target di Browserslist.
Sintassi e API sono due cose diverse: Babel traduce la grammatica, i polyfill aggiungono i metodi mancanti. Confonderle produce il bug che compila in locale e si rompe in produzione.
Nel 2026 serve ancora, ma in un ruolo diverso: i browser moderni supportano quasi tutto e esbuild e SWC hanno preso il suo posto negli strumenti predefiniti, perché fanno lo stesso lavoro molto più in fretta.
Resta insostituibile per le trasformazioni personalizzate e per i browser vecchi veri. Non è morto: è diventato specialistico.
Per il quadro degli strumenti che oggi lo orchestrano, vedi cos'è un bundler e cos'è Vite.