GetX State Management Flutter Tutorial

11 Min Read

In this blog, we will explore the features of getx package. So let’s get started.

Introduction to GetX State Management

GetX is the most powerful, extra lightweight, high-performance framework for building flutter apps. It is the combination of state management, dependency injection, and route management. There are many state management libraries are available in the flutter like MobX, BLoC, Redux, Provider, etc. But, Getx has a simple syntax and anyone easy to use. In addition, it reduces the many boilerplate codes. We don’t need context for creating snack bars, dialogs, and bottom sheets and we don’t need StreamControllers and StreamBuilders.

Principles of GetX

The Getx has 3 principles. There are,

  • Performance
  • Productivity
  • Organization

Features of GetX

  • Easy Navigation
  • Snack bars, dialogs, and bottom sheets with no contexts
  • Easy state management
  • Easy dependency injection
  • Easy key/value storage
  • Easy change theme
  • Easy Validators
  • Easy internationalization

Installing GetX

To install the getx of visit the GetX official page on and copy the latest version of the package. Then  Open pubspec.yaml file and add getx package in your dependency. Then don’t forget to run pub get, then only the package will add your project. 

   get: ^4.1.4

As of the time of writing this article, the current version of GetX is 4.1.4. It may change in feature. Please use the latest version. 

Alternatively, you can run the flutter pub add get command.

flutter pub add get

Now, import the package of your project.

import 'package:get/get.dart';

Then, Instead of using MaterialApp change it into the GetMaterialApp, Example Code given below,

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  Widget build(BuildContext context) {
    return GetMaterialApp(                 
      title: 'Flutter Demo',
      theme: ThemeData(
        visualDensity: VisualDensity.adaptivePlatformDensity,
      home: MyHomePage(),

Getting Started With GetX

Now, we explore the features of getx one by one.

Route Management

In the old method, we use Navigator. Now we don’t need any lengthy code.

Navigate to a new screen:;

To close snack bars, dialogs, bottom sheets, 


This method is used to go to the next screen and remove the previous screen. This method is helpful when we use SplashScreens, login screens and etc.;

This method is used to go to the next screen and remove all previous routes. This method is useful when we use shopping carts, polls, and tests, etc.


If you prefer navigation with named routes you can these methods. Initially, we need to define the routes,

void main() {
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => MyHomePage()),
        GetPage(name: '/second', page: () => Second()),
          name: '/third',
          page: () => Third(),
          transition: Transition.zoom  

Navigate to a new screen with a name.


This method is used to go to the next screen and remove the previous screen. This method is helpful when we use SplashScreens, login screens and etc.


This method is used to go to the next screen and remove all previous routes. This method is useful when we use shopping carts, polls, and tests, etc.


If any route is missed, that makes a 404 error. To handle the non-defined routes, we can use the unknown route.

void main() {
      unknownRoute: GetPage(name: '/notfound', page: () => UnknownRoutePage()),
      initialRoute: '/',
      getPages: [
        GetPage(name: '/', page: () => MyHomePage()),
        GetPage(name: '/second', page: () => Second()),

In getx, we don’t need any context for creating snack bars, dialogs, and bottom sheets.


Get.snackbar('Hi', 'i am a modern snackbar');




    child: Wrap(
      children: <Widget>[
          leading: Icon(Icons.music_note),
          title: Text('Music'),
          onTap: () {}
          leading: Icon(Icons.videocam),
          title: Text('Video'),
          onTap: () {},

State Management

Getx has two different state managers. They are,

  1. Simple State Manager (GetBuilder)
  2. Reactive state manager (GetX/Obx)

Simple State Manager (GetBuilder)

In Simple State Manager, it updates only the required widgets and the state manager uses less memory(~ 0MB). It does not need a change notifier.

First, create a controller class and extends GetxController. Then write your method/function and use update() to update the counter variable on UI.

class Controller extends GetxController {
  int counter = 0;
  void increment() {

In Getx, you don’t need a stateful widget. Wrap your existing widget as GetBuilder and give the Controller a parameter. Then initialize the controller using the init property. In the builder property, give your widget. The sample code is given below,

  init: Controller(), // INIT IT ONLY THE FIRST TIME
  builder: (_) => Text(

Note: Initialize the controller only one time. Don’t initialize the same controller in another place. In second-time use ReBuilder for the same controller.

Reactive state manager (GetX/Obx)

In Reactive State Manager you don’t need any StreamControllers, StreamBuilders, and other stuff.

Simply create a variable,

var name = 'Shibu';

Make it observable. To make it observable, simply add the “.obs” end of it.

var name = 'Shibu'.obs;

Update the variable as per your need,

name.value='Code With Flutter';

To update the UI as dynamic, wrap your existing widget as Obx. Example code is given below,

Obx(() => Text("${}"));

That’s all. It’s that simple.

For Example of Reactive State Manager,

class Controller extends GetxController{
  var count = 0.obs;
  increment() => count++;
class Home extends StatelessWidget {
  Widget build(context) {
    final Controller c = Get.put(Controller());
    return Scaffold(
      appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),
      body: Center(child: ElevatedButton(
              child: Text("Go to Other"), onPressed: () =>,
          FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
class Other extends StatelessWidget {
  final Controller c = Get.find();
  Widget build(context){
     return Scaffold(body: Center(child: Text("${c.count}")));

Dependency Management

One of the main features of Getx is simple and powerful dependency management. So we don’t need Provider context and inheritedWidget.

Instancing methods

To implement the dependency injection, there are four types of methods are available.

  1. Get.put()
  2. Get.lazyPut
  3. Get.putAsync
  4. Get.create

The Get.put() method is the most common way of injecting dependency. For Example,

Controller controller = Get.put(Controller());

To keep the dependency as an entire session, you can add the permanent property as true. For Example,

Get.put<LoginController>(LoginController(), permanent: true);

 It will be instantiated only when is used. For Example,

Get.lazyPut<Controller>(() => Controller());

If you want to use an asynchronous instance, you can use Get.putAsync.

Get.putAsync<YourAsyncClass>( () async => await YourAsyncClass() );

It creates a new instance of the dependency every time Get.find is called.

Get.Create<SomeClass>(() => SomeClass());
Get.Create<LoginController>(() => LoginController());

Using instantiated methods/classes

To use the injected dependency in another class, you can use Get.find() method. For Example,

final controller = Get.find<Controller>();
// OR
Controller controller = Get.find();

For more information about getx visit official documentation.

Share this Article