GetX — легкий мікро-фреймворк для Flutter, який об'єднує управління станом, навігацію та впровадження залежностей в одному пакеті. Розроблений Аміром Хоссейном Абдорашиді, GetX пропонує мінімальний boilerplate: без Stream, без ChangeNotifier, без BuildContext для навігації. За даними pub.dev, GetX набрав понад 13 тисяч лайків, ставши одним із найпопулярніших Flutter-пакетів.
Головне
GetX — all-in-one мікро-фреймворк для Flutter, який вирішує три основні завдання розробки: управління станом (State Management), навігація (Routing) та впровадження залежностей (DI). GetX не потребує Stream, ChangeNotifier, Builders або підписок — всю реактивність забезпечують Rx-обгортки на основі GetValue та GetStream, які працюють у десятки разів швидше за ChangeNotifier.
GetX позиціонується як альтернатива зв'язці Provider + Navigator + get_it/kiwi. Замість встановлення трьох різних пакетів та написання 10 рядків конфігурації, GetX дає все з коробки одним рядком: GetMaterialApp замість MaterialApp. Навігація працює через Get.to(NextScreen()) без BuildContext, а DI — через Get.put(Service()) без Provider-дерева.
За даними Flutter Community Survey 2025, GetX використовується в 43% Flutter-проектів. Основні причини вибору: мінімальний поріг входу (5 хвилин на освоєння), відсутність boilerplate (код скорочується на 60-70% порівняно з Provider або BLoC) та швидка розробка MVP. Критики відзначають порушення принципу розподілу відповідальності та складність налагодження.
Obx — реактивний віджет GetX, що перебудовується при зміні Rx-змінних. Obx не потребує підписки, dispose або Builder-функцій — досить обернути віджет в Obx та використовувати всередині Rx-змінну. Obx автоматично відстежує, які Rx-змінні використовуються, та перемальовує тільки при їх зміні.
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}'));
}Rx-змінні: .obs — геттер, що обгортає будь-яке значення в Rx-об'єкт. GetX надає типізовані Rx-класи: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. Всі Rx-змінні поводяться як звичайні примітиви: count++, name.value = 'Hello', items.add(item). Зміна автоматично сповіщає Obx-підписників.
GetBuilder — альтернатива Obx без Rx, що працює через ручний виклик update(). GetBuilder.filter — для точкового оновлення за ID-ключами. Obx швидший (автоматичне відстеження залежностей), GetBuilder передбачуваніший (явний виклик оновлення). Рекомендується Obx для простих сценаріїв та GetBuilder для складних віджетів з безліччю залежностей.
GetxController — базовий клас для бізнес-логіки з підтримкою життєвого циклу. GetxController має методи: onInit() (ініціалізація), onReady() (після першого фрейму), onClose() (очищення ресурсів). На відміну від ChangeNotifier та StateNotifier, GetxController автоматично керує підписками: при знищенні сторінки всі Rx-змінні та Workers відписуються.
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 — реактивні утиліти GetX: ever (викликається при кожній зміні), once (тільки при першій зміні), debounce (із затримкою), interval (не частіше N разів на секунду). Workers вирішують типові задачі: валідація полів (debounce), аналітика (once), синхронізація (ever). Workers автоматично відписуються при виклику onClose(), запобігаючи витокам пам'яті.
Навігація GetX не потребує BuildContext для переходу між екранами. Замість Navigator.push(context, MaterialPageRoute(...)) використовується Get.to(NextScreen()) — виклик з будь-якого місця, включаючи Controller без доступу до BuildContext. GetX підтримує іменовані маршрути, анімації, middleware та передачу аргументів без MaterialPageRoute.
// Звичайна навігація
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // замінити поточний маршрут
Get.offAll(HomeScreen()); // очистити стек
// Іменовані маршрути
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');
// Middleware
GetPage(
name: '/profile',
page: () => ProfileScreen(),
middlewares: [AuthMiddleware()],
)GetPage та GetPages: GetX використовує GetPages замість routes в MaterialApp. Middleware — перевірка авторизації, редиректи, аналітика перед входом на екран. Transition — вбудовані анімації переходу: fadeIn, zoom, leftToRight, topToBottom. Bindings — клас, що ініціалізує Controller та залежності при вході на маршрут. Bindings вирішують проблему лінивої ініціалізації: Controller створюється тільки коли екран відкрито.
Get.put — реєстрація екземпляра в DI-контейнері. Get.find — отримання екземпляра з контейнера. Get.lazyPut — лінива ініціалізація (створюється при першому виклику find). Get.putAsync — асинхронна ініціалізація (для сервісів з init). Get.delete — видалення з контейнера (викликається автоматично Bindings при знищенні маршруту).
| Метод | Коли створюється | Коли видаляється |
|---|---|---|
| Get.put | Негайно | Get.delete або onClose |
| Get.lazyPut | При першому find | Get.delete або onClose |
| Get.putAsync | Після виконання Future | Get.delete або onClose |
| Get.create | При кожному find (нова фабрика) | Ні |
GetX DI — найпростіший DI-контейнер у Flutter. Немає Provider-дерева, немає Module, немає Scope. Get.put(Repository()) в Controller або main.dart робить об'єкт доступним у будь-якому місці додатку через Get.find<Repository>(). GetX DI також підтримує тегування (tag: 'api') та перманентність (permanent: true) для запобігання видаленню.
Продуктивність GetX заснована на Rx-обгортках, що працюють через GetStream — власну реалізацію Stream, оптимізовану під Flutter. За бенчмарками GetX, Rx-змінні в 2-3 рази швидші за ChangeNotifier та в 5-7 разів швидші за BLoC при частих оновленнях (30+ fps). GetX не використовує BuildContext для підписок, що виключає перебудову дерева віджетів при навігації.
Кращі практики: використовуйте GetBuilder замість Obx для віджетів з великою кількістю дочірніх елементів (списки, таблиці). Розділяйте Controller за функціональними модулями, а не один величезний Controller на сторінку. Використовуйте Bindings для ініціалізації Controller, а не Get.put в build-методі. GetView — скорочений StatelessWidget з доступом до Controller через controller без Get.find.
Відомі обмеження: GetX використовує глобальні змінні (Get.find, Get.to), що може ускладнити тестування. Мокінг залежностей через GetX потребує Get.replace() або Get.reset() між тестами. Для ізоляції рекомендується Get.testMode = true. GetX не рекомендується для додатків, що вимагають суворої архітектури з чіткими межами шарів — у цьому випадку краще використовувати BLoC або Riverpod з кодогенерацією.
Часті запитання
GetX — мікро-фреймворк зі своїм DI, навігацією та Rx-реактивністю. Provider — тільки управління станом через ChangeNotifier та InheritedWidget. GetX не потребує BuildContext, має вбудовану навігацію та DI, скорочує boilerplate на 60-70%. Provider використовує стандартний Flutter Navigator та потребує сторонніх рішень для DI. GetX швидший у розробці, Provider — ближчий до нативного Flutter API.
Workers — утиліти для реактивної обробки змін Rx-змінних. ever — колбек на кожну зміну, once — тільки на першу, debounce — із затримкою (для пошукового поля), interval — не частіше N разів (для аналітики). Workers оголошуються в onInit() GetxController та автоматично відписуються в onClose(). Це замінює ручний addListener/removeListener з ChangeNotifier.
GetX надає Get.testMode = true для включення тестового режиму. Залежності замінюються через Get.replace<Service>(mockService). Між тестами викликається Get.reset() для очищення DI-контейнера. Controller тестуються напряму без Flutter: final c = CounterController(); c.increment(); expect(c.count.value, 1). Для віджетів з Obx використовуйте tester.pumpWidget з InjectMocker.
GetX підходить для проектів будь-якого розміру, але потребує дисципліни. Для великих проектів (10+ екранів) використовуйте: Bindings для ізоляції Controller, модулі (файли GetPages на фічу), GetView замість ручного Get.find в build. Основний ризик — зловживання глобальним доступом (Get.find у будь-якому місці). Строгі code review та архітектурні гайди вирішують цю проблему. Багато продакшен-додатків з мільйонами користувачів працюють на GetX.
Bindings — клас, що пов'язує маршрут з його залежностями. При вході на екран Binding створює Controller та сервіси через Get.lazyPut, при виході — видаляє їх. Bindings реалізують ліниву ініціалізацію: Controller не існує в пам'яті, поки екран не відкрито. Це економить RAM та час запуску додатку. Оголошуються в GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також