In inTouch siamo abituati a prendere decisioni tecniche che hanno effetti diretti su tempi, costi e qualità del prodotto. Quando si parla di sviluppo mobile, i confronti che troviamo online spesso si fermano alle tabelle di feature o ai benchmark sintetici. Utili, certo, ma raramente rivelano cosa succede davvero quando un team apre l’editor e inizia a scrivere codice.
Per questo abbiamo messo alla prova tre approcci in modo empirico: SwiftUI (nativo iOS), Kotlin Multiplatform con Compose Multiplatform (codice condiviso + UI per piattaforma) e Flutter (UI e logica unificate con un runtime proprio). Il banco di prova è Splitwise, una piccola app che calcola la divisione di una spesa tra più persone con una percentuale di mancia. È semplice abbastanza da essere realizzabile in un pomeriggio, ma completa il quadro: state management, input con formattazione localizzata, focus della tastiera, una navigazione essenziale e calcoli derivati dal modello.
La sorpresa non è stata il risultato finale (le tre versioni fanno esattamente la stessa cosa), ma il percorso per arrivarci: densità del codice molto diversa, modelli mentali divergenti, livelli di integrazione con la piattaforma che cambiano radicalmente la curva di sviluppo.
Perché Splitwise è un test credibile
Non abbiamo cercato l’app “accademica” ideale: ci serviva un micro-caso d’uso che assomigliasse alla quotidianità dei progetti. Splitwise mette in fila tutte le piccole frizioni che in produzione fanno la differenza: validare un input decimale, formattarlo secondo la valuta e la locale del dispositivo, propagare correttamente lo stato, gestire il passaggio da una view all’altra senza introdurre accoppiamenti, verificare che il calcolo derivato si aggiorni sempre quando cambia uno qualunque dei suoi input.
È una via di mezzo tra giocattolo e reale: abbastanza piccola da completare in poche ore, abbastanza concreta da far emergere differenze architetturali. Per un confronto “onesto”, è difficile trovare di meglio.
Densità del codice e filosofia del framework
La prima evidenza è quantitativa: SwiftUI chiude l’intera app in circa 75 righe, Flutter in circa 238, KMP/Compose in circa 281. Gli ordini di grandezza sono questi, anche considerando varianti minime di stile e formattazione.
Questa non è una “gara a chi scrive meno”: la quantità di codice è un riflesso della filosofia. SwiftUI tende a condensare stato, logica e interfaccia dentro un singolo contenitore dichiarativo; la piattaforma si occupa dell’infrastruttura invisibile. Compose pretende esplicitazione: grafi di navigazione, confini tra moduli, astrazioni expect/actual per toccare le API di sistema. Flutter chiede gestione manuale di controller e ciclo di vita, ma restituisce un flusso prevedibile e strumenti di sviluppo molto rapidi.
In pratica, SwiftUI massimizza la produttività nel breve, Compose punta a una struttura che regge la crescita, Flutter resta l’opzione pragmatica per arrivare presto su più piattaforme con un buon compromesso tra controllo e velocità.
Architettura: implicito, esplicito, imperativo
La differenza più profonda è architetturale.
SwiftUI mette il turbo alla produttività grazie a un dichiarativo “implicito”: proprietà annotate con @State, computed properties che si ricalcolano quando cambia uno qualsiasi degli input, binding bidirezionali con la sintassi $. Perfino la navigazione può diventare un dettaglio di stile: un modificatore sul controllo giusto e la view “si apre”. È una scelta che abbatte il rumore attorno al “cosa”, ma toglie visibilità sul “come”.
Compose ribalta l’approccio: tutto è esplicito. Il grafo di navigazione esiste sul serio e vive fuori dalle schermate; lo stato e le dipendenze dei calcoli derivati vanno dichiarati, con remember e derivedStateOf, perché la ricomposizione è un meccanismo consapevole. Se vuoi formattare una valuta “alla iOS” e “alla Android”, introduci un’interfaccia in commonMain e la implementi in iosMain e androidMain con expect/actual. È più lavoro all’inizio, ma riduce l’ambiguità quando il progetto si fa ampio.
Flutter mantiene una spina dorsale imperativa: controller per i campi di testo, listener sugli input, setState() per propagare l’aggiornamento alla UI, dispose() per pulire le risorse. Non è chic, ma è trasparente. In cambio, offre hot reload tra i migliori in circolazione: ritmo di iterazione altissimo, soprattutto nelle fasi di prototipazione e tuning dell’interfaccia.
State management: reattività invisibile vs controllo fine
Sul piano dello state management, i tre mondi hanno identità forti. Con SwiftUI, gli @State e la composizione per proprietà calcolate nascondono un sistema reattivo automatico: definisci i dati e il framework è responsabile della coerenza tra modello e UI. La trade-off è chiara: zero configurazione, meno leve di ottimizzazione “fine”.
Compose adotta una reattività esplicita: il calcolo di totalPerPerson non è una “proprietà magica”, è una funzione derivata che si invalida quando (e solo quando) cambiano le sue dipendenze. Questo evita ricalcoli non necessari e ti costringe a ragionare sulle fonti di verità. È un “costo” iniziale che si trasforma in vantaggio quando i calcoli si moltiplicano, magari con chiamate di rete o trasformazioni pesanti.
In Flutter, l’aggiornamento di stato passa spesso da setState() o da un package di state management (Provider, Riverpod, Bloc, MobX). Anche nel caso più semplice, però, l’idea resta: la UI è una funzione del modello, ma l’invalidazione la chiedi tu. È un approccio diretto, che scala con disciplina e convenzioni di team.
Navigazione: dal “funziona e basta” al grafo formale
La navigazione è un rivelatore affidabile dell’anima del framework. Con SwiftUI, un Picker con .navigationLink può generare automaticamente una nuova schermata, gestire la transizione, impostare il back e propagare il valore selezionato via binding. Poche righe per un risultato “magico”, a costo di vedere poco della meccanica sottostante.
Compose mette in carta e inchiostro lo stack: NavHost, rotte nominate, callback di ritorno. Il codice è più lungo per due schermate, ma leggibile quando diventano venti: le dipendenze sono ricercabili, i percorsi sono centralizzati, la logica è meno “sparsa”.
Flutter adotta un imperativo tipizzato: Navigator.push restituisce un Future, attendi un valore e lo usi per aggiornare lo stato. È lineare, evita la magia e si presta bene a scenari in cui devi “passare indietro” risultati concreti.
Integrazione con la piattaforma: nativo, astratto, a pacchetti
La localizzazione e la formattazione della valuta sono piccoli dettagli che in produzione si moltiplicano. Qui si vede bene la differenza.
SwiftUI pigia l’acceleratore del nativo: .currency(code: Locale.current.currency?.identifier ?? "EUR") e hai formattazione coerente con il sistema, senza dipendenze esterne. Anche focus della tastiera, accessibilità e dinamiche di sistema seguono la stessa coerenza.
KMP/Compose spinge sulle astrazioni corrette: dichiari in commonMain le funzioni per ottenere simbolo e formato, implementi in iosMain e androidMain. È un investimento che ripaga quando ti serve condividere davvero la logica tra piattaforme, senza rinunciare a comportamenti “da piattaforma”.
Flutter si appoggia ai pacchetti (ad es. intl per date e valute): una soluzione matura, coerente e portabile. È un modello potente perché modulare, ma costituisce una dipendenza in più dove i nativi offrono l’API out-of-the-box.
Performance: differenze minime qui, scelte importanti altrove
In un’app delle dimensioni di WeSplit le performance di runtime sono pressoché indistinguibili: SwiftUI renderizza nativo su iOS, Compose compila a nativo su Android e iOS (per la logica condivisa con KMP), Flutter disegna con Skia e mantiene un framerate costante. La parte interessante non è il tempo di esecuzione del calcolo (trascurabile), ma dove e quando avvengono i ricalcoli e quanto controllo hai sul loro invalidamento. SwiftUI fa molto “al posto tuo”, Compose ti chiede di essere esplicito, Flutter delega a te (o al package di stato) le strategie di invalidazione.
Testing e manutenibilità: dal file unico alla modularità
Dal punto di vista del testing, la singola vista SwiftUI è comoda, ma meno adatta a testare in isolamento parti di logica se non le estrai in moduli separati. Il preview canvas di Xcode resta un superpotere per il feedback visivo, e questo compensa parzialmente l’assenza di test granulari quando il progetto è piccolo.
Compose/KMP offre la miglior separazione dei ruoli: logica condivisa in commonMain testabile con unit test puri, UI per piattaforma testabile con strumenti dedicati (compose testing su Android, snapshot/strumenti su iOS). È un modello che incoraggia a costruire architetture scalabili.
Flutter ha un ottimo testing di widget, ma quando si usano controller e listener è necessario essere rigorosi nella pulizia delle risorse anche nei test, replicando i pattern del codice di produzione. Con librerie di stato mature (Bloc/Riverpod), il testing diventa lineare.
Developer Experience: ciò che senti mentre lavori
L’esperienza dello sviluppatore è ciò che non sta nelle specifiche ma pesa nella giornata.
Con SwiftUI, la combinazione di concisione, preview e integrazione con Xcode permette di produrre velocemente schermate e flussi base, con messaggi di errore spesso informativi. Il prerequisito hardware (Mac + Xcode) e il focus su iOS/macOS sono il rovescio della medaglia.
Compose/KMP chiede più tempo di setup e una comprensione reale di expect/actual e dei confini di progetto. In cambio, restituisce un impianto architetturale chiaro e ripegabile su più piattaforme nel modo giusto: business logic condivisa, UI nativa per piattaforma dove serve.
Flutter vince per hot reload e tooling (VS Code/Android Studio) fluidi: ritmo di iterazione rapidissimo e un ecosistema di package che copre la maggior parte dei bisogni. Il costo è la gestione manuale di alcune risorse e una curva di apprendimento leggermente diversa per chi proviene dal mondo nativo.
Un estratto di codice (SwiftUI) che riassume l’idea
Un solo blocco, minimale ma rappresentativo: stato, calcolo derivato, input localizzato e gestione del focus.
import SwiftUI
struct ContentView: View {
@State private var checkAmount = 0.0
@State private var numberOfPeople = 2
@State private var tipPercentage = 20
@FocusState private var amountIsFocused: Bool
private var totalPerPerson: Double {
let people = Double(numberOfPeople + 2) // range base 2..<
let tipValue = checkAmount * Double(tipPercentage) / 100.0
return (checkAmount + tipValue) / max(people, 1) // guardrail
}
var body: some View {
NavigationStack {
Form {
Section("Importo") {
TextField("Totale conto",
value: $checkAmount,
format: .currency(code: Locale.current.currency?.identifier ?? "EUR"))
.keyboardType(.decimalPad)
.focused($amountIsFocused)
}
Section("Persone e mancia") {
Stepper("Persone: \(numberOfPeople + 2)", value: $numberOfPeople, in: 0...97)
Picker("Mancia", selection: $tipPercentage) {
ForEach([0,10,15,20,25], id: \.self) { Text("\($0)%") }
}
.pickerStyle(.segmented)
}
Section("Per persona") {
Text(totalPerPerson,
format: .currency(code: Locale.current.currency?.identifier ?? "EUR"))
.font(.title.weight(.semibold))
}
}
.toolbar {
if amountIsFocused {
ToolbarItemGroup(placement: .keyboard) {
Spacer()
Button("Fine") { amountIsFocused = false }
}
}
}
.navigationTitle("WeSplit")
}
}
}
``
Questo pezzo condensa l’essenza di SwiftUI: poche righe, comportamento dichiarativo, integrazione nativa, focus gestito in modo espressivo, calcolo derivato “trasparente” rispetto alle dipendenze.
Scalabilità e organizzazione del team
Il punto non è tanto “quanto ci metto a fare WeSplit”, ma cosa succede quando Splitwise diventa un’app con 20 schermate, sincronizzazione, analytics, feature flag, A/B test, design system interno e più squadre che lavorano in parallelo.
SwiftUI regge benissimo fino a un certo livello di complessità; poi serve introdurre separazione modulare (view-model, coordinatori, layer di servizio), spesso ispirandosi a pattern noti del mondo iOS. Il vantaggio iniziale di velocità resta, ma richiede disciplina architetturale via via maggiore.
KMP/Compose è pensato per scalare: nav graph, moduli condivisi, confini netti tra UI e logica, contratti expect/actual per i dettagli di piattaforma. È un ecosistema che premia i team più grandi con codice riusabile e indipendenza tra piattaforma e funzionalità.
Flutter scala bene se si adottano convenzioni chiare: state management coerente, cartelle e modularizzazione, limitare gli “shortcut” tipici dell’MVP quando si entra in fase di prodotto. L’ecosistema aiuta, ma conta la disciplina del team.
Costi, time-to-market e rischi
Dal punto di vista economico, scegliere un framework significa distribuire costi nel tempo in modo diverso.
SwiftUI: time-to-market iOS molto rapido, costo marginale per feature incrementali basso. Costi aggiuntivi se in futuro serve Android (non c’è “riuso” diretto di UI o logica).
KMP/Compose: investimento iniziale maggiore, risparmio strutturale quando la logica di business è davvero condivisibile (validazioni complesse, calcoli, sincronizzazione, regole di dominio). UI separate preservano la “sensazione nativa”.
Flutter: un solo codice per iOS/Android (e oltre), tempi rapidi e ottimo tooling. Rischi contenuti se si scelgono pacchetti maturi e si controlla il debito tecnico (gestione risorse, aggiornamento dipendenze, performance del layer grafico in casi particolari).
Criteri decisionali pratici (da usare davvero)
Evitando slogan, questi sono i criteri che consigliamo di applicare in azienda quando si deve scegliere:
Piattaforme target nei prossimi 18–24 mesi: solo iOS, iOS+Android, anche Desktop/Web?
Natura della logica di business: quanto è condivisibile? È stabile e centralizzabile?
Competenze del team oggi e tra 6 mesi: Swift, Kotlin, Dart; disponibilità reale di profili.
Vincoli di UX: pretendi look-and-feel nativo o coerenza cross-platform è preferibile?
Governance e compliance: integrazione con feature di sistema (privacy, accessibilità, pagamenti, device capabilities).
Budget & roadmap: MVP rapido vs prodotto con orizzonte pluriennale.
Applicando questi criteri:
SwiftUI è la scelta naturale se l’obiettivo è iOS e vuoi massimizzare velocità e integrazione.
KMP/Compose è giustificata quando il valore del riuso della logica è alto e prevedi crescita.
Flutter è l’opzione più pragmatica per MVP multipiattaforma o roadmap aggressive su due piattaforme con un team unico.
Cosa ci portiamo a casa
Sviluppare Splitwise tre volte non produce tre app diverse: produce tre esperienze di sviluppo diverse. SwiftUI è eleganza e velocità quando l’ecosistema Apple è la tua casa. Compose è struttura e scalabilità quando devi crescere su più piattaforme senza perdere controllo. Flutter è pragmatismo e produttività quando contano tempo e coerenza su iOS+Android con una sola codebase.
La scelta giusta dipende dagli obiettivi del prodotto, dai vincoli del mercato e dalla maturità del team. Se stai valutando quale strada prendere, il nostro suggerimento è di non fermarti a tabelle e benchmark: prototipa una feature reale nei candidati principali e misura non solo il tempo, ma anche la qualità del codice, la chiarezza architetturale e la serenità di sviluppo che ciascun framework ti restituisce.
Sviluppare la stessa app in SwiftUI, KMP/Compose e Flutter: tre strade reali verso lo stesso risultato
In inTouch siamo abituati a prendere decisioni tecniche che hanno effetti diretti su tempi, costi e qualità del prodotto. Quando si parla di sviluppo mobile, i confronti che troviamo online spesso si fermano alle tabelle di feature o ai benchmark sintetici. Utili, certo, ma raramente rivelano cosa succede davvero quando un team apre l’editor e inizia a scrivere codice.
Per questo abbiamo messo alla prova tre approcci in modo empirico: SwiftUI (nativo iOS), Kotlin Multiplatform con Compose Multiplatform (codice condiviso + UI per piattaforma) e Flutter (UI e logica unificate con un runtime proprio). Il banco di prova è Splitwise, una piccola app che calcola la divisione di una spesa tra più persone con una percentuale di mancia. È semplice abbastanza da essere realizzabile in un pomeriggio, ma completa il quadro: state management, input con formattazione localizzata, focus della tastiera, una navigazione essenziale e calcoli derivati dal modello.
La sorpresa non è stata il risultato finale (le tre versioni fanno esattamente la stessa cosa), ma il percorso per arrivarci: densità del codice molto diversa, modelli mentali divergenti, livelli di integrazione con la piattaforma che cambiano radicalmente la curva di sviluppo.
Perché Splitwise è un test credibile
Non abbiamo cercato l’app “accademica” ideale: ci serviva un micro-caso d’uso che assomigliasse alla quotidianità dei progetti. Splitwise mette in fila tutte le piccole frizioni che in produzione fanno la differenza: validare un input decimale, formattarlo secondo la valuta e la locale del dispositivo, propagare correttamente lo stato, gestire il passaggio da una view all’altra senza introdurre accoppiamenti, verificare che il calcolo derivato si aggiorni sempre quando cambia uno qualunque dei suoi input.
È una via di mezzo tra giocattolo e reale: abbastanza piccola da completare in poche ore, abbastanza concreta da far emergere differenze architetturali. Per un confronto “onesto”, è difficile trovare di meglio.
Densità del codice e filosofia del framework
La prima evidenza è quantitativa: SwiftUI chiude l’intera app in circa 75 righe, Flutter in circa 238, KMP/Compose in circa 281. Gli ordini di grandezza sono questi, anche considerando varianti minime di stile e formattazione.
Questa non è una “gara a chi scrive meno”: la quantità di codice è un riflesso della filosofia.
SwiftUI tende a condensare stato, logica e interfaccia dentro un singolo contenitore dichiarativo; la piattaforma si occupa dell’infrastruttura invisibile. Compose pretende esplicitazione: grafi di navigazione, confini tra moduli, astrazioni expect/actual per toccare le API di sistema. Flutter chiede gestione manuale di controller e ciclo di vita, ma restituisce un flusso prevedibile e strumenti di sviluppo molto rapidi.
In pratica, SwiftUI massimizza la produttività nel breve, Compose punta a una struttura che regge la crescita, Flutter resta l’opzione pragmatica per arrivare presto su più piattaforme con un buon compromesso tra controllo e velocità.
Architettura: implicito, esplicito, imperativo
La differenza più profonda è architetturale.
SwiftUI mette il turbo alla produttività grazie a un dichiarativo “implicito”: proprietà annotate con
@State, computed properties che si ricalcolano quando cambia uno qualsiasi degli input, binding bidirezionali con la sintassi$. Perfino la navigazione può diventare un dettaglio di stile: un modificatore sul controllo giusto e la view “si apre”. È una scelta che abbatte il rumore attorno al “cosa”, ma toglie visibilità sul “come”.Compose ribalta l’approccio: tutto è esplicito. Il grafo di navigazione esiste sul serio e vive fuori dalle schermate; lo stato e le dipendenze dei calcoli derivati vanno dichiarati, con
rememberederivedStateOf, perché la ricomposizione è un meccanismo consapevole. Se vuoi formattare una valuta “alla iOS” e “alla Android”, introduci un’interfaccia incommonMaine la implementi iniosMaineandroidMainconexpect/actual. È più lavoro all’inizio, ma riduce l’ambiguità quando il progetto si fa ampio.Flutter mantiene una spina dorsale imperativa: controller per i campi di testo, listener sugli input,
setState()per propagare l’aggiornamento alla UI,dispose()per pulire le risorse. Non è chic, ma è trasparente. In cambio, offre hot reload tra i migliori in circolazione: ritmo di iterazione altissimo, soprattutto nelle fasi di prototipazione e tuning dell’interfaccia.State management: reattività invisibile vs controllo fine
Sul piano dello state management, i tre mondi hanno identità forti. Con SwiftUI, gli
@Statee la composizione per proprietà calcolate nascondono un sistema reattivo automatico: definisci i dati e il framework è responsabile della coerenza tra modello e UI. La trade-off è chiara: zero configurazione, meno leve di ottimizzazione “fine”.Compose adotta una reattività esplicita: il calcolo di
totalPerPersonnon è una “proprietà magica”, è una funzione derivata che si invalida quando (e solo quando) cambiano le sue dipendenze. Questo evita ricalcoli non necessari e ti costringe a ragionare sulle fonti di verità. È un “costo” iniziale che si trasforma in vantaggio quando i calcoli si moltiplicano, magari con chiamate di rete o trasformazioni pesanti.In Flutter, l’aggiornamento di stato passa spesso da
setState()o da un package di state management (Provider, Riverpod, Bloc, MobX). Anche nel caso più semplice, però, l’idea resta: la UI è una funzione del modello, ma l’invalidazione la chiedi tu. È un approccio diretto, che scala con disciplina e convenzioni di team.Navigazione: dal “funziona e basta” al grafo formale
La navigazione è un rivelatore affidabile dell’anima del framework. Con SwiftUI, un Picker con
.navigationLinkpuò generare automaticamente una nuova schermata, gestire la transizione, impostare il back e propagare il valore selezionato via binding. Poche righe per un risultato “magico”, a costo di vedere poco della meccanica sottostante.Compose mette in carta e inchiostro lo stack:
NavHost, rotte nominate, callback di ritorno. Il codice è più lungo per due schermate, ma leggibile quando diventano venti: le dipendenze sono ricercabili, i percorsi sono centralizzati, la logica è meno “sparsa”.Flutter adotta un imperativo tipizzato:
Navigator.pushrestituisce un Future, attendi un valore e lo usi per aggiornare lo stato. È lineare, evita la magia e si presta bene a scenari in cui devi “passare indietro” risultati concreti.Integrazione con la piattaforma: nativo, astratto, a pacchetti
La localizzazione e la formattazione della valuta sono piccoli dettagli che in produzione si moltiplicano. Qui si vede bene la differenza.
SwiftUI pigia l’acceleratore del nativo:
.currency(code: Locale.current.currency?.identifier ?? "EUR")e hai formattazione coerente con il sistema, senza dipendenze esterne. Anche focus della tastiera, accessibilità e dinamiche di sistema seguono la stessa coerenza.KMP/Compose spinge sulle astrazioni corrette: dichiari in
commonMainle funzioni per ottenere simbolo e formato, implementi iniosMaineandroidMain. È un investimento che ripaga quando ti serve condividere davvero la logica tra piattaforme, senza rinunciare a comportamenti “da piattaforma”.Flutter si appoggia ai pacchetti (ad es.
intlper date e valute): una soluzione matura, coerente e portabile. È un modello potente perché modulare, ma costituisce una dipendenza in più dove i nativi offrono l’API out-of-the-box.Performance: differenze minime qui, scelte importanti altrove
In un’app delle dimensioni di WeSplit le performance di runtime sono pressoché indistinguibili: SwiftUI renderizza nativo su iOS, Compose compila a nativo su Android e iOS (per la logica condivisa con KMP), Flutter disegna con Skia e mantiene un framerate costante. La parte interessante non è il tempo di esecuzione del calcolo (trascurabile), ma dove e quando avvengono i ricalcoli e quanto controllo hai sul loro invalidamento. SwiftUI fa molto “al posto tuo”, Compose ti chiede di essere esplicito, Flutter delega a te (o al package di stato) le strategie di invalidazione.
Testing e manutenibilità: dal file unico alla modularità
Dal punto di vista del testing, la singola vista SwiftUI è comoda, ma meno adatta a testare in isolamento parti di logica se non le estrai in moduli separati. Il preview canvas di Xcode resta un superpotere per il feedback visivo, e questo compensa parzialmente l’assenza di test granulari quando il progetto è piccolo.
Compose/KMP offre la miglior separazione dei ruoli: logica condivisa in
commonMaintestabile con unit test puri, UI per piattaforma testabile con strumenti dedicati (compose testing su Android, snapshot/strumenti su iOS). È un modello che incoraggia a costruire architetture scalabili.Flutter ha un ottimo testing di widget, ma quando si usano controller e listener è necessario essere rigorosi nella pulizia delle risorse anche nei test, replicando i pattern del codice di produzione. Con librerie di stato mature (Bloc/Riverpod), il testing diventa lineare.
Developer Experience: ciò che senti mentre lavori
L’esperienza dello sviluppatore è ciò che non sta nelle specifiche ma pesa nella giornata.
Con SwiftUI, la combinazione di concisione, preview e integrazione con Xcode permette di produrre velocemente schermate e flussi base, con messaggi di errore spesso informativi. Il prerequisito hardware (Mac + Xcode) e il focus su iOS/macOS sono il rovescio della medaglia.
Compose/KMP chiede più tempo di setup e una comprensione reale di
expect/actuale dei confini di progetto. In cambio, restituisce un impianto architetturale chiaro e ripegabile su più piattaforme nel modo giusto: business logic condivisa, UI nativa per piattaforma dove serve.Flutter vince per hot reload e tooling (VS Code/Android Studio) fluidi: ritmo di iterazione rapidissimo e un ecosistema di package che copre la maggior parte dei bisogni. Il costo è la gestione manuale di alcune risorse e una curva di apprendimento leggermente diversa per chi proviene dal mondo nativo.
Un estratto di codice (SwiftUI) che riassume l’idea
Un solo blocco, minimale ma rappresentativo: stato, calcolo derivato, input localizzato e gestione del focus.
Questo pezzo condensa l’essenza di SwiftUI: poche righe, comportamento dichiarativo, integrazione nativa, focus gestito in modo espressivo, calcolo derivato “trasparente” rispetto alle dipendenze.
Scalabilità e organizzazione del team
Il punto non è tanto “quanto ci metto a fare WeSplit”, ma cosa succede quando Splitwise diventa un’app con 20 schermate, sincronizzazione, analytics, feature flag, A/B test, design system interno e più squadre che lavorano in parallelo.
SwiftUI regge benissimo fino a un certo livello di complessità; poi serve introdurre separazione modulare (view-model, coordinatori, layer di servizio), spesso ispirandosi a pattern noti del mondo iOS. Il vantaggio iniziale di velocità resta, ma richiede disciplina architetturale via via maggiore.
KMP/Compose è pensato per scalare: nav graph, moduli condivisi, confini netti tra UI e logica, contratti expect/actual per i dettagli di piattaforma. È un ecosistema che premia i team più grandi con codice riusabile e indipendenza tra piattaforma e funzionalità.
Flutter scala bene se si adottano convenzioni chiare: state management coerente, cartelle e modularizzazione, limitare gli “shortcut” tipici dell’MVP quando si entra in fase di prodotto. L’ecosistema aiuta, ma conta la disciplina del team.
Costi, time-to-market e rischi
Dal punto di vista economico, scegliere un framework significa distribuire costi nel tempo in modo diverso.
Criteri decisionali pratici (da usare davvero)
Evitando slogan, questi sono i criteri che consigliamo di applicare in azienda quando si deve scegliere:
Applicando questi criteri:
Cosa ci portiamo a casa
Sviluppare Splitwise tre volte non produce tre app diverse: produce tre esperienze di sviluppo diverse.
SwiftUI è eleganza e velocità quando l’ecosistema Apple è la tua casa. Compose è struttura e scalabilità quando devi crescere su più piattaforme senza perdere controllo. Flutter è pragmatismo e produttività quando contano tempo e coerenza su iOS+Android con una sola codebase.
La scelta giusta dipende dagli obiettivi del prodotto, dai vincoli del mercato e dalla maturità del team. Se stai valutando quale strada prendere, il nostro suggerimento è di non fermarti a tabelle e benchmark: prototipa una feature reale nei candidati principali e misura non solo il tempo, ma anche la qualità del codice, la chiarezza architetturale e la serenità di sviluppo che ciascun framework ti restituisce.
Articoli recenti
Categorie
Business Overview
Contatti
Via Mario Giuntini 29, 56021- Navacchio (PI)
(+39) 339 8041866
info@intouch-srl.com
Lunedì-Venerdì: 09:00 - 18:00