UI library
Copy-paste o headless: quale approccio scegliere per la UI
Il copy-paste ti dà il codice, l’headless ti dà il comportamento. La scelta cambia chi aggiorna i componenti, quanto pesa il bundle e quanto controllo hai sull’accessibilità.
In sintesi
- Copy-paste significa possesso: il codice è tuo, gli aggiornamenti sono tuoi.
- Headless significa delega: comportamento e accessibilità arrivano dal pacchetto.
- Il criterio non è la moda: è chi mantiene quel codice tra due anni e quanto è stabile il tuo design.
La prima decisione non è quale libreria installare. È dove vive il codice del componente. Da quella risposta dipendono aggiornamenti, bundle, accessibilità e costo di uscita.
Due modelli, non due gusti
| Dimensione | Copy-paste | Headless |
|---|---|---|
| Dove vive il codice | Nel tuo repository | Nel pacchetto installato |
| Aggiornamenti | Li fai tu, file per file | Arrivano con la versione |
| Stile | Libero, nessun tema imposto | Devi scriverlo tu |
| Accessibilità | La erediti, ma puoi romperla | Gestita dal pacchetto |
| Bundle | Solo ciò che copi | Dipende dal tree-shaking |
| Costo di uscita | Basso: il codice è già tuo | Medio: riscrivi le API |
Quando conviene il copy-paste
Conviene quando il design è specifico, il componente è semplice e il team vuole possedere ogni riga. Un bottone, una card, un badge: il copy-paste elimina una dipendenza e lascia visibile ciò che succede.
Conviene meno quando il componente è complesso. Un dialog accessibile fatto a mano richiede focus trap, ripristino del focus, scroll lock, gestione di Escape e ARIA corrette. Copiare 400 righe che non capisci non è possesso: è debito con una data di scadenza.
Quando conviene l’headless
Conviene quando il comportamento è difficile e lo stile è tuo. Le primitive headless separano le due cose: tu scrivi l’aspetto, loro garantiscono tastiera, focus e ARIA.
Il test che smaschera la scelta sbagliata
# Quanti file copiati contengono logica di focus o tastiera?
rg -l "focus|keydown|aria-" src/components/ui | wc -l
# Quante dipendenze entrano per un solo componente?
npx depcheck
Se i file copiati contengono gestione di focus e tastiera, stai mantenendo un comportamento che nessuno ha progettato per essere mantenuto. Quella è la zona dove l’headless vince.
La via di mezzo, spiegata bene
Il modello shadcn/ui è copy-paste di componenti che usano primitive headless. Il codice è tuo, il comportamento difficile resta delegato. Funziona perché il confine è chiaro: tu possiedi lo stile, la primitiva possiede l’interazione.
- Installa la primitiva come dipendenza.
- Copia solo il componente che devi adattare.
- Non riscrivere il comportamento della primitiva.
- Documenta la versione da cui hai copiato, per poter confrontare gli aggiornamenti.
Cosa dicono i numeri del catalogo
EneUI indicizza 111.985 componenti da 1.472 librerie (31 ottobre 2026). Il catalogo è utile proprio qui: mostra quanti modelli diversi convivono, con fonte, licenza e dipendenze per ogni record, invece di presentare un solo modello come universale.
Domande frequenti
Copy-paste è meglio di una libreria?
Non in assoluto. È meglio quando vuoi possedere lo stile e il componente è semplice. È peggio quando copi comportamento complesso che non sapresti mantenere.
L’headless è accessibile per definizione?
No. La primitiva gestisce il comportamento, ma tu puoi rompere l’accessibilità con markup, ordine di tabulazione o stili che nascondono il focus.
Il copy-paste aumenta il bundle?
Spesso lo riduce, perché non installi il resto della libreria. Ma se copi componenti che importano utility pesanti, il risparmio sparisce.
Come aggiorno componenti copiati?
Tieni nota della versione di origine e confronta i file, non sovrascrivere. Gli aggiornamenti manuali sono il costo reale del modello.
Posso mixare i due approcci?
Sì, ed è la scelta più comune. Tieni il confine esplicito: headless per l’interazione, copy-paste per l’aspetto.