Negli ultimi anni i Web Components sono tornati al centro dell'attenzione come soluzione nativa per creare interfacce modulari, riutilizzabili e indipendenti dai framework. Promettono portabilità, isolamento dello stile e interoperabilità totale. Ma convengono davvero? E soprattutto: quando usarli e quando no? In questo articolo vedremo cosa sono, come funzionano, i loro reali vantaggi, i limiti spesso sottovalutati e alcuni esempi concreti di utilizzo corretto.
Cosa sono i Web Components
I Web Components non sono una libreria o un framework. Sono un insieme di standard web supportati dai browser moderni che permettono di creare nuovi elementi HTML personalizzati. Si basano su tre tecnologie principali:
- Custom Elements – permettono di definire nuovi tag HTML.
- Shadow DOM – consente l'isolamento di markup e CSS.
- HTML Templates – per definire strutture riutilizzabili.
Ma perché tutti ne parlano?
Il fascino dei Web Components nasce da alcune promesse molto allettanti:
- Funzionano ovunque: React, Vue, Angular, Svelte, Vanilla JS.
- Non dipendono da un ecosistema specifico.
- Sono standard del web, non mode passeggere.
- Possono essere usati come veri e propri tag HTML.
In teoria, scrivi un componente una volta e lo riutilizzi ovunque. In pratica.. dipende. Ecco un esempio base, reale, semplice ma completo di Web Component:
class MyButton extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: "open" });
const button = document.createElement("button");
button.textContent = "Cliccami";
const style = document.createElement("style");
style.textContent = `
button {
background: #6200ee;
color: white;
border: none;
padding: 10px 16px;
border-radius: 4px;
cursor: pointer;
}
`;
shadow.append(style, button);
}
}
customElements.define("my-button", MyButton);
Ora puoi usarlo in qualsiasi HTML. Senza React. Senza Vue. Senza build. Senza dipendenze.
Quando i Web Components sono una scelta eccellente
Design system e componenti condivisi: se devi creare una libreria di componenti riutilizzabile tra più progetti e framework diversi, i Web Components sono perfetti. Esempi:
- Bottoni.
- Modali.
- Tooltip.
- Input custom.
- Widget riutilizzabili.
Aziende come Google, Microsoft e Salesforce li usano proprio per questo motivo.
Microfrontend: in architetture a microfrontend, dove parti dell'app sono sviluppate da team diversi con stack diversi, i Web Components funzionano come "collante universale". Ogni team può usare il suo framework, ma esportare i componenti come Web Components.
Widget embeddabili: se devi fornire un widget integrabile su siti esterni (es: chat, form, mappe, calendari), i Web Components sono una soluzione eccellente.
Isolamento di stile: grazie allo Shadow DOM, i CSS sono isolati. Niente conflitti, niente override casuali, niente !important. Questo è uno dei vantaggi più sottovalutati.
Quando non convengono
I Web Components non offrono:
- State management.
- Routing.
- Reactivity avanzata.
- Data binding.
Tutte cose che framework come React, Vue o Angular gestiscono in modo eccellente. Puoi implementarli a mano, ma rischi di reinventare la ruota.
Se il team è esperto in React o Vue, forzare i Web Components può rallentare lo sviluppo e aumentare la complessità. Inoltre i Web Components non sono ideali per il rendering lato server. Google li indicizza, ma non sempre in modo ottimale.
Per quanto riguarda poi ebugging e tooling, l'ecosistema è molto più povero rispetto a React/Vue:
- Meno devtools.
- Meno librerie.
- Meno pattern consolidati.
Web Components e framework: nemici o alleati?
Un grande mito è che Web Components sostituiscano i framework. Non è vero. Il vero valore sta nell'integrazione. Puoi usare Web Components dentro React, Vue o Angular. Il problema principale è la gestione degli eventi e delle props che non è sempre immediata.
Proviamo ad esempio a passare dati a un Web Component:
class UserCard extends HTMLElement {
connectedCallback() {
const name = this.getAttribute("name");
const age = this.getAttribute("age");
this.innerHTML = `
${name}, ${age} anni
`;
}
}
customElements.define("user-card", UserCard);
Questo funziona, ma non è reattivo automaticamente.
Un Web Component può poi emettere eventi:
this.dispatchEvent(new CustomEvent("user-clicked", {
detail: { id: 123 }
}));
E può essere ascoltato:
document.querySelector("my-component")
.addEventListener("user-clicked", e => console.log(e.detail));
Shadow DOM: benedizione o maledizione?
Lo Shadow DOM isola:
- CSS.
- Markup.
- Eventi (in parte).
Questo è fantastico per evitare conflitti, ma rende più complesso: personalizzare lo stile, testare e fare debug. Molti sviluppatori lo trovano frustrante all'inizio.
Scrivere Web Components a mano risulta poi verboso. Fortunatamente esistono librerie come Lit:
import { LitElement, html, css } from 'lit';
class MyButton extends LitElement {
static styles = css`
button { background: purple; color: white; }
`;
render() {
return html`Clicca`;
}
}
customElements.define('my-button', MyButton);
Stencil è invece molto usata per il design system enterprise.
Ma allora: convengono o no?
Dipende. Convengono se:
- Devi creare componenti riutilizzabili tra stack diversi.
- Hai bisogno di isolamento forte.
- Vuoi distribuire widget esterni.
- Stai costruendo un design system.
Non convengono se:
- Stai costruendo una SPA complessa.
- Hai bisogno di stato globale e routing.
- Il team è molto orientato ai framework.
- Vuoi massima velocità di sviluppo.
Conclusione
I Web Components non sono il futuro di tutte le web app. Ma sono una parte importante del futuro del web. Sono uno strumento potente ma, come tutti gli strumenti potenti, vanno usati nel contesto giusto.Non sostituiscono React o Vue. Li completano.
Chi li usa bene ottiene:
- Portabilità.
- Manutenibilità.
- Indipendenza tecnologica.
Chi li usa male.. si ritrova a scrivere un framework a mano.