GetX — um micro-framework leve para Flutter que combina gerenciamento de estado, navegação e injeção de dependência em um único pacote. Desenvolvido por Amir Hossein Abdorashidi, GetX oferece boilerplate mínimo: sem Stream, sem ChangeNotifier, sem BuildContext para navegação. De acordo com pub.dev, GetX acumulou mais de 13 mil curtidas, tornando-se um dos pacotes Flutter mais populares.
Pontos-chave
GetX — um micro-framework tudo-em-um para Flutter que resolve três tarefas principais de desenvolvimento: gerenciamento de estado, navegação (roteamento) e injeção de dependência (DI). GetX não requer Stream, ChangeNotifier, Builders ou assinaturas — toda a reatividade é fornecida por wrappers Rx baseados em GetValue e GetStream, que funcionam dezenas de vezes mais rápido que ChangeNotifier.
GetX é posicionado como uma alternativa ao combo Provider + Navigator + get_it/kiwi. Em vez de instalar três pacotes diferentes e escrever 10 linhas de configuração, GetX fornece tudo pronto com uma única linha: GetMaterialApp em vez de MaterialApp. A navegação funciona via Get.to(NextScreen()) sem BuildContext, e a DI via Get.put(Service()) sem árvore Provider.
De acordo com a Pesquisa da Comunidade Flutter 2025, GetX é usado em 43% dos projetos Flutter. As principais razões para escolhê-lo: limite mínimo de entrada (5 minutos para aprender), sem boilerplate (código reduzido em 60-70% comparado a Provider ou BLoC) e desenvolvimento rápido de MVP. Críticos apontam violação do princípio de separação de responsabilidades e complexidade de depuração.
Obx — um widget reativo do GetX que se reconstrói quando variáveis Rx mudam. Obx não requer assinatura, dispose ou funções Builder — basta envolver o widget em Obx e usar uma variável Rx dentro. Obx rastreia automaticamente quais variáveis Rx são usadas e redesenha apenas quando elas mudam.
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}'));
}Variáveis Rx: .obs — um getter que envolve qualquer valor em um objeto Rx. GetX fornece classes Rx tipadas: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. Todas as variáveis Rx se comportam como primitivas normais: count++, name.value = 'Hello', items.add(item). A mudança notifica automaticamente os assinantes Obx.
GetBuilder — uma alternativa ao Obx sem Rx, funcionando via chamada manual de update(). GetBuilder.filter — para atualizações direcionadas por chaves ID. Obx é mais rápido (rastreamento automático de dependências), GetBuilder é mais previsível (chamada de atualização explícita). Obx é recomendado para cenários simples e GetBuilder para widgets complexos com muitas dependências.
GetxController — uma classe base para lógica de negócios com suporte a ciclo de vida. GetxController tem métodos: onInit() (inicialização), onReady() (após o primeiro frame), onClose() (limpeza de recursos). Ao contrário de ChangeNotifier e StateNotifier, GetxController gerencia assinaturas automaticamente: quando a página é destruída, todas as variáveis Rx e Workers são canceladas.
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 — utilitários reativos do GetX: ever (chamado em cada mudança), once (apenas na primeira mudança), debounce (com atraso), interval (não mais que N vezes por segundo). Workers resolvem tarefas comuns: validação de campos (debounce), análise (once), sincronização (ever). Workers cancelam automaticamente a assinatura quando onClose() é chamado, prevenindo vazamentos de memória.
A navegação do GetX não requer BuildContext para transitar entre telas. Em vez de Navigator.push(context, MaterialPageRoute(...)), usa-se Get.to(NextScreen()) — chamável de qualquer lugar, incluindo um Controller sem acesso a BuildContext. GetX suporta rotas nomeadas, animações, middleware e passagem de argumentos sem MaterialPageRoute.
// Navegação padrão
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // substituir rota atual
Get.offAll(HomeScreen()); // limpar pilha
// Rotas nomeadas
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');
// Middleware
GetPage(
name: '/profile',
page: () => ProfileScreen(),
middlewares: [AuthMiddleware()],
)GetPage e GetPages: GetX usa GetPages em vez de routes no MaterialApp. Middleware — verificações de autenticação, redirecionamentos, análise antes de entrar em uma tela. Transition — animações de transição integradas: fadeIn, zoom, leftToRight, topToBottom. Bindings — uma classe que inicializa o Controller e dependências ao entrar em uma rota. Bindings resolvem o problema de inicialização preguiçosa: o Controller é criado apenas quando a tela é aberta.
Get.put — registra uma instância no contêiner DI. Get.find — recupera uma instância do contêiner. Get.lazyPut — inicialização preguiçosa (criado na primeira chamada find). Get.putAsync — inicialização assíncrona (para serviços com init). Get.delete — remove do contêiner (chamado automaticamente por Bindings quando a rota é destruída).
| Método | Quando é criado | Quando é removido |
|---|---|---|
| Get.put | Imediatamente | Get.delete ou onClose |
| Get.lazyPut | No primeiro find | Get.delete ou onClose |
| Get.putAsync | Após Future completar | Get.delete ou onClose |
| Get.create | Em cada find (nova fábrica) | Não |
DI do GetX — o contêiner DI mais simples no Flutter. Sem árvore Provider, sem Module, sem Scope. Get.put(Repository()) no Controller ou main.dart torna o objeto acessível em qualquer lugar do aplicativo via Get.find<Repository>(). O DI do GetX também suporta tagging (tag: 'api') e permanência (permanent: true) para prevenir remoção.
Desempenho do GetX é baseado em wrappers Rx que funcionam através do GetStream — uma implementação personalizada de Stream otimizada para Flutter. De acordo com benchmarks do GetX, variáveis Rx são 2-3 vezes mais rápidas que ChangeNotifier e 5-7 vezes mais rápidas que BLoC com atualizações frequentes (30+ fps). GetX não usa BuildContext para assinaturas, o que elimina a reconstrução da árvore de widgets durante a navegação.
Melhores práticas: use GetBuilder em vez de Obx para widgets com muitos elementos filhos (listas, tabelas). Divida o Controller por módulos funcionais em vez de um Controller enorme por página. Use Bindings para inicializar o Controller, não Get.put no método build. GetView — um StatelessWidget abreviado com acesso ao Controller via controller sem Get.find.
Limitações conhecidas: GetX usa variáveis globais (Get.find, Get.to), o que pode dificultar testes. Mockar dependências via GetX requer Get.replace() ou Get.reset() entre testes. Para isolamento, Get.testMode = true é recomendado. GetX não é recomendado para aplicações que exigem arquitetura estrita com limites claros entre camadas — neste caso, BLoC ou Riverpod com geração de código é preferível.
Perguntas frequentes
GetX — um micro-framework com seu próprio DI, navegação e reatividade Rx. Provider — apenas gerenciamento de estado via ChangeNotifier e InheritedWidget. GetX não requer BuildContext, tem navegação e DI integrados, reduzindo boilerplate em 60-70%. Provider usa o Navigator padrão do Flutter e requer soluções de terceiros para DI. GetX é mais rápido no desenvolvimento, Provider é mais próximo da API nativa do Flutter.
Workers — utilitários para processamento reativo de mudanças em variáveis Rx. ever — callback em cada mudança, once — apenas na primeira mudança, debounce — com atraso (para campos de busca), interval — não mais que N vezes (para análise). Workers são declarados no onInit() do GetxController e cancelam assinatura automaticamente no onClose(). Isso substitui addListener/removeListener manual com ChangeNotifier.
GetX fornece Get.testMode = true para ativar o modo de teste. Dependências são substituídas via Get.replace<Service>(mockService). Entre testes, Get.reset() é chamado para limpar o contêiner DI. Controllers são testados diretamente sem Flutter: final c = CounterController(); c.increment(); expect(c.count.value, 1). Para widgets com Obx, use tester.pumpWidget com InjectMocker.
GetX é adequado para projetos de qualquer tamanho, mas requer disciplina. Para projetos grandes (10+ telas), use: Bindings para isolar Controller, módulos (arquivos GetPages por funcionalidade), GetView em vez de Get.find manual no build. O principal risco é o abuso do acesso global (Get.find em qualquer lugar). Revisões de código rigorosas e guias arquiteturais resolvem isso. Muitos aplicativos de produção com milhões de usuários rodam em GetX.
Bindings — uma classe que conecta uma rota com suas dependências. Ao entrar em uma tela, o Binding cria o Controller e serviços via Get.lazyPut, e os remove ao sair. Bindings implementam inicialização preguiçosa: o Controller não existe em memória até que a tela seja aberta. Isso economiza RAM e tempo de inicialização do aplicativo. São declarados em GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também