GetX — un micro-framework leggero per Flutter che combina gestione dello stato, navigazione e dependency injection in un unico pacchetto. Sviluppato da Amir Hossein Abdorashidi, GetX offre un boilerplate minimo: senza Stream, senza ChangeNotifier, senza BuildContext per la navigazione. Secondo pub.dev, GetX ha accumulato oltre 13 mila like, diventando uno dei pacchetti Flutter più popolari.
Punti chiave
GetX — un micro-framework tutto-in-uno per Flutter che risolve tre attività principali di sviluppo: gestione dello stato, navigazione (routing) e dependency injection (DI). GetX non richiede Stream, ChangeNotifier, Builders o sottoscrizioni — tutta la reattività è fornita da wrapper Rx basati su GetValue e GetStream, che funzionano decine di volte più velocemente di ChangeNotifier.
GetX si posiziona come alternativa alla combinazione Provider + Navigator + get_it/kiwi. Invece di installare tre pacchetti diversi e scrivere 10 righe di configurazione, GetX fornisce tutto pronto con una singola riga: GetMaterialApp invece di MaterialApp. La navigazione funziona tramite Get.to(NextScreen()) senza BuildContext, e la DI tramite Get.put(Service()) senza albero Provider.
Secondo il Sondaggio della Community Flutter 2025, GetX è utilizzato nel 43% dei progetti Flutter. Le ragioni principali per sceglierlo: soglia d'ingresso minima (5 minuti per imparare), nessun boilerplate (codice ridotto del 60-70% rispetto a Provider o BLoC) e sviluppo MVP rapido. I critici notano la violazione del principio di separazione delle responsabilità e la complessità del debug.
Obx — un widget reattivo GetX che si ricostruisce quando le variabili Rx cambiano. Obx non richiede sottoscrizione, dispose o funzioni Builder — basta avvolgere il widget in Obx e usare una variabile Rx al suo interno. Obx traccia automaticamente quali variabili Rx vengono utilizzate e ridisegna solo quando cambiano.
class CounterController extends GetxController {
final count = 0.obs;
void increment() => count++;
}
class CounterScreen extends StatelessWidget {
final controller = Get.put(CounterController());
@override
Widget build(context) => Obx(() => Text('${controller.count}'));
}Variabili Rx: .obs — un getter che avvolge qualsiasi valore in un oggetto Rx. GetX fornisce classi Rx tipizzate: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. Tutte le variabili Rx si comportano come primitivi normali: count++, name.value = 'Hello', items.add(item). Il cambiamento notifica automaticamente gli abbonati Obx.
GetBuilder — un'alternativa a Obx senza Rx, che funziona tramite chiamata manuale a update(). GetBuilder.filter — per aggiornamenti mirati per chiavi ID. Obx è più veloce (tracciamento automatico delle dipendenze), GetBuilder è più prevedibile (chiamata di aggiornamento esplicita). Obx è raccomandato per scenari semplici e GetBuilder per widget complessi con molte dipendenze.
GetxController — una classe base per la logica di business con supporto del ciclo di vita. GetxController ha metodi: onInit() (inizializzazione), onReady() (dopo il primo frame), onClose() (pulizia delle risorse). A differenza di ChangeNotifier e StateNotifier, GetxController gestisce automaticamente le sottoscrizioni: quando la pagina viene distrutta, tutte le variabili Rx e Workers vengono cancellati.
class AuthController extends GetxController {
final user = Rx<User?>(null);
final isLoading = false.obs;
@override
void onInit() {
ever(isLoading, (_) => print('Loading: $isLoading'));
super.onInit();
}
Future<void> login(String email, String password) async {
isLoading.value = true;
user.value = await api.login(email, password);
isLoading.value = false;
}
}Workers — utility reattive di GetX: ever (chiamato a ogni cambiamento), once (solo al primo cambiamento), debounce (con ritardo), interval (non più di N volte al secondo). I Workers risolvono compiti tipici: validazione campi (debounce), analisi (once), sincronizzazione (ever). I Workers si cancellano automaticamente quando viene chiamato onClose(), prevenendo perdite di memoria.
La navigazione GetX non richiede BuildContext per transitare tra schermate. Invece di Navigator.push(context, MaterialPageRoute(...)), si usa Get.to(NextScreen()) — chiamabile da qualsiasi punto, incluso un Controller senza accesso a BuildContext. GetX supporta route nominate, animazioni, middleware e passaggio di argomenti senza MaterialPageRoute.
// Navigazione standard
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // sostituisci route corrente
Get.offAll(HomeScreen()); // svuota pila
// Route nominate
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');
// Middleware
GetPage(
name: '/profile',
page: () => ProfileScreen(),
middlewares: [AuthMiddleware()],
)GetPage e GetPages: GetX usa GetPages invece di routes in MaterialApp. Middleware — controlli di autenticazione, reindirizzamenti, analisi prima di entrare in una schermata. Transition — animazioni di transizione integrate: fadeIn, zoom, leftToRight, topToBottom. Bindings — una classe che inizializza il Controller e le dipendenze all'ingresso di una route. I Bindings risolvono il problema dell'inizializzazione pigra: il Controller viene creato solo quando la schermata viene aperta.
Get.put — registra un'istanza nel contenitore DI. Get.find — recupera un'istanza dal contenitore. Get.lazyPut — inizializzazione pigra (creato alla prima chiamata find). Get.putAsync — inizializzazione asincrona (per servizi con init). Get.delete — rimuove dal contenitore (chiamato automaticamente da Bindings alla distruzione della route).
| Metodo | Quando viene creato | Quando viene rimosso |
|---|---|---|
| Get.put | Immediatamente | Get.delete o onClose |
| Get.lazyPut | Al primo find | Get.delete o onClose |
| Get.putAsync | Dopo il completamento di Future | Get.delete o onClose |
| Get.create | Ad ogni find (nuova factory) | No |
DI di GetX — il contenitore DI più semplice in Flutter. Nessun albero Provider, nessun Module, nessun Scope. Get.put(Repository()) nel Controller o main.dart rende l'oggetto accessibile ovunque nell'app tramite Get.find<Repository>(). Il DI di GetX supporta anche tagging (tag: 'api') e permanenza (permanent: true) per prevenire la rimozione.
Le prestazioni di GetX si basano su wrapper Rx che funzionano tramite GetStream — un'implementazione Stream personalizzata ottimizzata per Flutter. Secondo i benchmark di GetX, le variabili Rx sono 2-3 volte più veloci di ChangeNotifier e 5-7 volte più veloci di BLoC con aggiornamenti frequenti (30+ fps). GetX non usa BuildContext per le sottoscrizioni, eliminando la ricostruzione dell'albero dei widget durante la navigazione.
Best practice: usa GetBuilder invece di Obx per widget con molti elementi figli (liste, tabelle). Dividi il Controller per moduli funzionali invece di un enorme Controller per pagina. Usa Bindings per inizializzare il Controller, non Get.put nel metodo build. GetView — uno StatelessWidget abbreviato con accesso al Controller tramite controller senza Get.find.
Limitazioni note: GetX usa variabili globali (Get.find, Get.to), che possono complicare i test. Il mocking delle dipendenze tramite GetX richiede Get.replace() o Get.reset() tra i test. Per l'isolamento, si raccomanda Get.testMode = true. GetX non è raccomandato per applicazioni che richiedono un'architettura rigorosa con chiari confini di strato — in questo caso, BLoC o Riverpod con generazione di codice è preferibile.
Domande frequenti
GetX — un micro-framework con proprio DI, navigazione e reattività Rx. Provider — solo gestione dello stato tramite ChangeNotifier e InheritedWidget. GetX non richiede BuildContext, ha navigazione e DI integrati, riducendo il boilerplate del 60-70%. Provider usa il Navigator standard di Flutter e richiede soluzioni di terze parti per il DI. GetX è più veloce nello sviluppo, Provider è più vicino all'API nativa di Flutter.
Workers — utility per l'elaborazione reattiva dei cambiamenti delle variabili Rx. ever — callback a ogni cambiamento, once — solo al primo cambiamento, debounce — con ritardo (per campi di ricerca), interval — non più di N volte (per analisi). I Workers vengono dichiarati in onInit() del GetxController e si cancellano automaticamente in onClose(). Questo sostituisce addListener/removeListener manuale con ChangeNotifier.
GetX fornisce Get.testMode = true per attivare la modalità test. Le dipendenze vengono sostituite tramite Get.replace<Service>(mockService). Tra i test, viene chiamato Get.reset() per pulire il contenitore DI. I Controller vengono testati direttamente senza Flutter: final c = CounterController(); c.increment(); expect(c.count.value, 1). Per widget con Obx, usa tester.pumpWidget con InjectMocker.
GetX è adatto a progetti di qualsiasi dimensione ma richiede disciplina. Per progetti grandi (10+ schermate), usa: Bindings per isolare il Controller, moduli (file GetPages per funzionalità), GetView invece di Get.find manuale in build. Il rischio principale è l'abuso dell'accesso globale (Get.find ovunque). Revisioni del codice rigorose e linee guida architetturali risolvono questo problema. Molte applicazioni di produzione con milioni di utenti funzionano su GetX.
Bindings — una classe che collega una route con le sue dipendenze. All'ingresso di una schermata, Binding crea il Controller e i servizi tramite Get.lazyPut, e li rimuove all'uscita. I Bindings implementano l'inizializzazione pigra: il Controller non esiste in memoria fino a quando la schermata non viene aperta. Questo risparmia RAM e tempo di avvio dell'app. Dichiarati in GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche