Design system
Migrare da MUI a shadcn/ui: ordine di lavoro e costi reali
La migrazione da MUI a shadcn/ui ha un ordine preciso e un costo che si conta in file, non in componenti. Token, componenti base, layout, componenti avanzati: cosa riscrivere e quando fermarsi.
In sintesi
- L'ordine è token, componenti base, layout, componenti avanzati: invertirlo significa riscrivere due volte.
- Il costo si misura in file che importano `@mui/material`, non nel numero di componenti disponibili.
- Il catalogo indicizza 153 componenti MUI e 61 shadcn al 1 novembre 2026: il confronto parte dai record.
- shadcn/ui non è versionato e non copre le data grid di MUI X: è il limite da dichiarare prima di iniziare.
La migrazione da MUI a shadcn/ui si fa in ordine fisso: token, componenti base, layout, componenti avanzati. Ogni fase si chiude su una schermata reale e si misura prima di passare alla successiva; il costo non è il numero di componenti, è il numero di file che importano MUI.
MUI non è una lista di componenti: porta un tema, il prop `sx`, una griglia e un sistema di stile. shadcn/ui non è un pacchetto: porta codice che copi nel progetto. La migrazione cambia proprietario, non solo sintassi.
L’ordine di lavoro, in cinque passi
- 1. Inventario: conta i file che importano `@mui/material` e i componenti distinti. Senza quel numero ogni stima è un’opinione.
- 2. Token: porta colori, spaziature e raggi in variabili CSS prima di toccare un componente. I token sono l’unico strato che sopravvive alla migrazione.
- 3. Componenti base: Button, Input, Label e Dialog per primi. Coprono la maggior parte delle schermate e fanno emergere subito i problemi di tema.
- 4. Layout: sostituisci Grid e Stack con CSS Grid e flex dove il layout è semplice. Tieni l’astrazione solo dove si ripaga.
- 5. Componenti avanzati: tabelle, date picker e autocomplete per ultimi. Costano di più e hanno meno equivalenti.
Perché i token vengono prima dei componenti
Se migri i componenti prima dei token, riscrivi ogni bottone due volte: una per farlo funzionare, una per farlo somigliare al design. I token sono l’unica parte che non cambia quando cambia il componente.
Da `sx` ai token semantici
Il prop `sx` vince perché è veloce, ma lega il colore al file. Con variabili CSS il componente chiede `--ui-bg` e non sa quale marca lo usa. La mappatura si scrive una volta e si verifica con un controllo di contrasto.
Dalla Grid al layout nativo
La Grid di MUI è un’astrazione su flex e grid. Se il layout è una pagina di marketing, CSS Grid nativo è più corto. Se è una dashboard con dodici widget, l’astrazione può ancora convenire: misurala su una schermata prima di decidere.
I costi reali, voce per voce
| Voce | Cosa riscrivi | Segnale nel codice | Costo |
|---|---|---|---|
| Token | Colori, spazi, raggi, tipografia | Colori scritti dentro `sx` | Una volta, prima di tutto |
| Base | Button, Input, Label, Dialog | Import da `@mui/material` | Per file, meccanico |
| Layout | Grid, Stack, Box | `sx={{ display: ... }}`, `Grid item` | Alto se il layout è annidato |
| Avanzati | Table, Autocomplete, DatePicker | Pacchetti MUI X | Alto: pochi equivalenti |
| Verifica | Focus, tastiera, screen reader | Test e checklist esistenti | Obbligatorio, non opzionale |
Il primo componente da migrare
Parti da un componente che usa tre cose: stato, focus e un’icona. Un Button con icona e stato disabled è un buon test; un Dialog è il secondo. Se questi due passano senza toccare il layout, il resto è ripetizione.
# 1. file che importano MUI: è il numero che decide il costo
rg -l "@mui/material|@mui/system" src | wc -l
# 2. componenti importati, ordinati per frequenza
rg -o 'from "@mui/material/([A-Za-z]+)"' -r '$1' src | sort | uniq -c | sort -rn
# 3. sostituisci un componente su un ramo, non tutto il sito
npx shadcn@latest init
npx shadcn@latest add button dialog input label
Il comando di inventario conta i file, non i componenti: è il numero che decide il costo. Se restituisce dodici, la migrazione è una singola revisione; se restituisce duecento, va spezzata per area e messa in un piano.
Quando fermarsi
Fermati se il prodotto è Material per scelta, se il team conosce l’API e se le schermate sono già coerenti. Fermati anche se usi MUI X in modo intensivo: shadcn/ui non ha un equivalente del Data Grid, e riscriverlo costa più del tema che stai lasciando.
Limite dichiarato: shadcn/ui non è un pacchetto versionato. Il codice è tuo, ma gli aggiornamenti di accessibilità e compatibilità li devi seguire a mano. MUI, con tutti i suoi difetti, ti manda un changelog.
I record di partenza sono /components/lib/mui con 153 componenti e /components/lib/shadcn con 61; per i bottoni la categoria è /components/cat/button. Il confronto tra approcci è in alternative a MUI, misurate, i criteri in come scegliere una libreria UI, il costo nel bundle in bundle size delle UI library e il modello copy-paste in copy-paste o headless. La licenza è la parte facile: shadcn/ui è MIT, Radix è MIT, Tailwind è MIT; il core di MUI è MIT, MUI X è commerciale.
Domande frequenti
Quanto costa migrare da MUI a shadcn/ui?
Costa il numero di file che importano MUI moltiplicato per il tempo di rifare una schermata; non esiste un prezzo unico. Conta prima i file con il comando di inventario, poi decidi.
Da quale componente si comincia?
Dai token, poi da Button, Input e Dialog. I token evitano di riscrivere due volte lo stesso componente, e i due componenti base fanno emergere subito i problemi di focus e tema.
Posso migrare una pagina alla volta?
Sì, ma solo dopo aver portato i token. Due temi in parallelo raddoppiano i bug di stile e rendono impossibile capire quale sistema ha vinto.
shadcn/ui è gratis?
Sì, il codice è distribuito con licenza MIT e finisce nel tuo repository. Il costo non è la licenza, è il mantenimento: gli aggiornamenti li segui tu.
Cosa non copre shadcn/ui?
Le data grid avanzate e i componenti complessi. MUI X li offre con licenza commerciale, e per quelli la migrazione costa più del tema che stai lasciando.