GetX — 상태 관리, 네비게이션 및 의존성 주입을 하나의 패키지에 결합한 Flutter용 경량 마이크로 프레임워크입니다. Amir Hossein Abdorashidi가 개발한 GetX는 최소한의 boilerplate를 제공합니다: Stream 불필요, ChangeNotifier 불필요, 네비게이션에 BuildContext 불필요.pub.dev에 따르면 GetX는 13,000개 이상의 좋아요를 획득하여 가장 인기 있는 Flutter 패키지 중 하나가 되었습니다.
주요 포인트
GetX — Flutter용 올인원 마이크로 프레임워크로, 상태 관리, 네비게이션(라우팅) 및 의존성 주입(DI)의 세 가지 주요 개발 작업을 해결합니다. GetX는 Stream, ChangeNotifier, Builders 또는 구독이 필요하지 않습니다 — 모든 반응성은 GetValue와 GetStream을 기반으로 하는 Rx 래퍼에 의해 제공되며, 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는 Flutter 프로젝트의 43%에서 사용됩니다. 선택하는 주요 이유: 최소 진입 장벽(5분 학습), boilerplate 없음(Provider 또는 BLoC 대비 코드 60-70% 감소), 빠른 MVP 개발. 비평가들은 관심사 분리 원칙 위반과 디버깅 복잡성을 지적합니다.
Obx — Rx 변수가 변경될 때 재구축되는 반응형 GetX 위젯입니다. 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 객체로 감싸는 getter입니다. GetX는 타입화된 Rx 클래스를 제공합니다: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. 모든 Rx 변수는 일반 프리미티브처럼 동작합니다: count++, name.value = 'Hello', items.add(item). 변경 사항은 자동으로 Obx 구독자에게 알립니다.
GetBuilder — 수동 update() 호출을 통해 작동하는 Rx 없는 Obx의 대안입니다. 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())를 사용합니다 — BuildContext 액세스 없이 Controller를 포함한 어디서든 호출 가능합니다. GetX는 명명된 라우트, 애니메이션, 미들웨어 및 MaterialPageRoute 없는 인수 전달을 지원합니다.
// 표준 네비게이션
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // 현재 라우트 교체
Get.offAll(HomeScreen()); // 스택 지우기
// 명명된 라우트
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');
// 미들웨어
GetPage(
name: '/profile',
page: () => ProfileScreen(),
middlewares: [AuthMiddleware()],
)GetPage 및 GetPages: GetX는 MaterialApp의 routes 대신 GetPages를 사용합니다. 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 — Flutter에서 가장 간단한 DI 컨테이너입니다. Provider 트리 없음, Module 없음, Scope 없음. Controller 또는 main.dart에서 Get.put(Repository())를 수행하면 Get.find<Repository>()를 통해 앱 어디서든 객체에 액세스할 수 있습니다. GetX DI는 태깅(tag: 'api') 및 영속성(permanent: true)도 지원하여 삭제를 방지합니다.
GetX 성능은 Flutter에 최적화된 사용자 정의 Stream 구현인 GetStream을 통해 작동하는 Rx 래퍼를 기반으로 합니다. GetX 벤치마크에 따르면 Rx 변수는 빈번한 업데이트(30+fps)에서 ChangeNotifier보다 2-3배, BLoC보다 5-7배 빠릅니다. GetX는 구독에 BuildContext를 사용하지 않으므로 네비게이션 중 위젯 트리 재구축을 제거합니다.
모범 사례: 많은 자식 요소(목록, 테이블)가 있는 위젯에는 Obx 대신 GetBuilder를 사용하세요. 페이지당 하나의 거대한 Controller 대신 기능 모듈별로 Controller를 분할하세요. Controller 초기화에는 build 메서드에서 Get.put 대신 Bindings를 사용하세요. GetView — Get.find 없이 controller를 통해 Controller에 액세스할 수 있는 단축된 StatelessWidget입니다.
알려진 제한사항: 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는 GetxController의 onInit()에서 선언되며 onClose()에서 자동으로 구독이 해제됩니다. 이는 ChangeNotifier로 수동 addListener/removeListener를 대체합니다.
GetX는 테스트 모드를 활성화하기 위해 Get.testMode = true를 제공합니다. 의존성은 Get.replace<Service>(mockService)를 통해 대체됩니다. 테스트 간에 DI 컨테이너를 정리하기 위해 Get.reset()이 호출됩니다. Controller는 Flutter 없이 직접 테스트됩니다: final c = CounterController(); c.increment(); expect(c.count.value, 1). Obx가 있는 위젯의 경우 InjectMocker와 함께 tester.pumpWidget을 사용하세요.
GetX는 모든 규모의 프로젝트에 적합하지만 규율이 필요합니다. 대규모 프로젝트(10+ 화면)의 경우 다음을 사용하세요: Controller 격리를 위한 Bindings, 기능별 GetPages 파일인 모듈, build에서 수동 Get.find 대신 GetView. 주요 위험은 전역 액세스의 남용입니다(어디서든 Get.find). 엄격한 코드 리뷰와 아키텍처 가이드라인이 이 문제를 해결합니다. 수백만 사용자가 있는 많은 프로덕션 애플리케이션이 GetX에서 실행됩니다.
Bindings — 라우트를 의존성에 연결하는 클래스입니다. 화면 진입 시 Binding은 Get.lazyPut을 통해 Controller와 서비스를 생성하고 종료 시 제거합니다. Bindings는 지연 초기화를 구현합니다: 화면이 열릴 때까지 Controller는 메모리에 존재하지 않습니다. 이는 RAM과 앱 시작 시간을 절약합니다. GetPage에서 선언됩니다: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.