rxget 0.1.0+3 copy "rxget: ^0.1.0+3" to clipboard
rxget: ^0.1.0+3 copied to clipboard

A lightweight reactive state management and dependency injection library for Dart and Flutter — pure and minimal.

rxget #

rxget is a lightweight, performance-focused fork of GetX — keeping only reactivity and dependency injection.
No routing, no UI helpers — just pure state management.

About Get #

  • GetX is an extra-light and powerful solution for Flutter. It combines high-performance state management and intelligent dependency injection quickly and practically.

  • GetX has 3 basic principles. This means that these are the priority for all resources in the library: PRODUCTIVITY, PERFORMANCE AND ORGANIZATION.

    • PERFORMANCE: GetX is focused on performance and minimum consumption of resources. GetX does not use Streams or ChangeNotifier.

    • PRODUCTIVITY: GetX uses an easy and pleasant syntax. No matter what you want to do, there is always an easier way with GetX. It will save hours of development and will provide the maximum performance your application can deliver.

      Generally, the developer should be concerned with removing controllers from memory. With GetX this is not necessary because resources are removed from memory when they are not used by default. If you want to keep it in memory, you must explicitly declare "permanent: true" in your dependency. That way, in addition to saving time, you are less at risk of having unnecessary dependencies on memory. Dependency loading is also lazy by default.

    • ORGANIZATION: GetX allows the total decoupling of the View, presentation logic, business logic, and dependency injection. You do not need context to access your controllers/blocs through an inheritedWidget, so you completely decouple your presentation logic and business logic from your visualization layer. You do not need to inject your Controllers/Models/Blocs classes into your widget tree through MultiProviders. For this, GetX uses its own dependency injection feature, decoupling the DI from its view completely. With GetX you know where to find each feature of your application, having clean code by default. In addition to making maintenance easy, this makes the sharing of modules something that until then in Flutter was unthinkable, something totally possible. BLoC was a starting point for organizing code in Flutter, it separates business logic from visualization. GetX is a natural evolution of this, not only separating the business logic but the presentation logic. Dependency injection is also decoupled, and the data layer is out of it all. You know where everything is, and all of this in an easier way than building a hello world. GetX is the easiest, practical, and scalable way to build high-performance applications with the Flutter SDK. It has a large ecosystem around it that works perfectly together, it's easy for beginners, and it's accurate for experts. It is secure, stable, up-to-date, and offers a huge range of APIs built-in that are not present in the default Flutter SDK.

  • GetX is not bloated. It has a multitude of features that allow you to start programming without worrying about anything, but each of these features are in separate containers and are only started after use. If you only use State Management, only State Management will be compiled. If you only use routes, nothing from the state management will be compiled.

  • GetX has a huge ecosystem, a large community, a large number of collaborators, and will be maintained as long as the Flutter exists. GetX too is capable of running with the same code on Android, iOS, Web, Mac, Linux, Windows, and on your server.

In addition, the entire development process can be completely automated, both on the server and on the front end with Get CLI.

In addition, to further increase your productivity, we have the extension to VSCode and the extension to Android Studio/Intellij

Installing #

Add Get to your pubspec.yaml file:

dependencies:
  get:

Import get in files that it will be used:

import 'package:rxget/get.dart';

Counter App with GetX #

The "counter" project created by default on new project on Flutter has over 100 lines (with comments). To show the power of Get, I will demonstrate how to make a "counter" changing the state with each click, switching between pages and sharing the state between screens, all in an organized way, separating the business logic from the view, in ONLY 26 LINES CODE INCLUDING COMMENTS.

  • Step 1: Create your business logic class and place all variables, methods and controllers inside it. You can make any variable observable using a simple ".obs".
class Controller extends GetxController{
  var count = 0.obs;
  increment() => count++;
}
  • Step 2: Create your View, use StatelessWidget and save some RAM, with Get you may no longer need to use StatefulWidget.
class Home extends StatelessWidget {

  @override
  Widget build(context) {

    // Instantiate your class using Get.put() to make it available for all "child" routes there.
    final Controller c = Get.put(Controller());

    return Scaffold(
      // Use Obx(()=> to update Text() whenever count is changed.
      appBar: AppBar(title: Obx(() => Text("Clicks: ${c.count}"))),

      // Replace the 8 lines Navigator.push by a simple Get.to(). You don't need context
      body: Center(child: ElevatedButton(
              child: Text("Go to Other"), onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (context) => Other())))),
      floatingActionButton:
          FloatingActionButton(child: Icon(Icons.add), onPressed: c.increment));
  }
}

class Other extends StatelessWidget {
  // You can ask Get to find a Controller that is being used by another page and redirect you to it.
  final Controller c = Get.find();

  @override
  Widget build(context){
     // Access the updated count variable
     return Scaffold(body: Center(child: Text("${c.count}")));
  }
}

Result:

This is a simple project but it already makes clear how powerful Get is. As your project grows, this difference will become more significant.

Get was designed to work with teams, but it makes the job of an individual developer simple.

Improve your deadlines, deliver everything on time without losing performance. Get is not for everyone, but if you identified with that phrase, Get is for you!

The Three pillars #

State management #

Get has two different state managers: the simple state manager (we'll call it GetBuilder) and the reactive state manager (GetX/Obx)

Reactive State Manager

Reactive programming can alienate many people because it is said to be complicated. GetX turns reactive programming into something quite simple:

  • You won't need to create StreamControllers.
  • You won't need to create a StreamBuilder for each variable
  • You will not need to create a class for each state.
  • You will not need to create a get for an initial value.
  • You will not need to use code generators

Reactive programming with Get is as easy as using setState.

Let's imagine that you have a name variable and want that every time you change it, all widgets that use it are automatically changed.

This is your count variable:

var name = 'Jonatas Borges';

To make it observable, you just need to add ".obs" to the end of it:

var name = 'Jonatas Borges'.obs;

And in the UI, when you want to show that value and update the screen whenever the values changes, simply do this:

Obx(() => Text("${controller.name}"));

That's all. It's that simple.

More details about state management

See an more in-depth explanation of state management here. There you will see more examples and also the difference between the simple state manager and the reactive state manager

You will get a good idea of GetX power.

Dependency management #

Get has a simple and powerful dependency manager that allows you to retrieve the same class as your Bloc or Controller with just 1 lines of code, no Provider context, no inheritedWidget:

Controller controller = Get.put(Controller()); // Rather Controller controller = Controller();
  • Note: If you are using Get's State Manager, pay more attention to the bindings API, which will make it easier to connect your view to your controller.

Instead of instantiating your class within the class you are using, you are instantiating it within the Get instance, which will make it available throughout your App. So you can use your controller (or class Bloc) normally

Tip: Get dependency management is decoupled from other parts of the package, so if for example, your app is already using a state manager (any one, it doesn't matter), you don't need to rewrite it all, you can use this dependency injection with no problems at all

controller.fetchApi();

Controller controller = Get.find(); //Yes, it looks like Magic, Get will find your controller, and will deliver it to you. You can have 1 million controllers instantiated, Get will always give you the right controller.


And then you will be able to recover your controller data that was obtained back there:

```dart
Text(controller.textFromApi);

More details about dependency management

See a more in-depth explanation of dependency management here

Widget-Scoped Dependency Injection with GetIn

After removing navigator and UI features, the automatic disposal system was removed. The GetIn widget solves this by providing widget-scoped dependency injection with automatic disposal when the widget is removed from the tree.

Single Dependency
GetIn(
  single: MyController(),
  child: MyWidget(),
)

When this widget is disposed, MyController will automatically be removed from memory.

Multiple Dependencies
GetIn(
  multiple: [
    UserController(),
    SettingsController(),
    ThemeController(),
  ],
  child: MyWidget(),
)

All dependencies are automatically disposed when the GetIn widget is removed.

Single + Multiple
GetIn(
  single: MainController(),
  multiple: [HelperController(), UtilsController()],
  child: MyWidget(),
)

Access dependencies anywhere in the widget tree with Get.find<Type>():

final controller = Get.find<MyController>();

Useful tips #

.observables (also known as Rx Types) have a wide variety of internal methods and operators.

Is very common to believe that a property with .obs IS the actual value... but make no mistake! We avoid the Type declaration of the variable, because Dart's compiler is smart enough, and the code looks cleaner, but:

var message = 'Hello world'.obs;
print( 'Message "$message" has Type ${message.runtimeType}');

Even if message prints the actual String value, the Type is RxString!

So, you can't do message.substring( 0, 4 ). You have to access the real value inside the observable: The most "used way" is .value, but, did you know that you can also use...

final name = 'GetX'.obs;
// only "updates" the stream, if the value is different from the current one.
name.value = 'Hey';

// All Rx properties are "callable" and returns the new value.
// but this approach does not accepts `null`, the UI will not rebuild.
name('Hello');

// is like a getter, prints 'Hello'.
name() ;

/// numbers:

final count = 0.obs;

// You can use all non mutable operations from num primitives!
count + 1;

// Watch out! this is only valid if `count` is not final, but var
count += 1;

// You can also compare against values:
count > 2;

/// booleans:

final flag = false.obs;

// switches the value between true/false
flag.toggle();


/// all types:

// Sets the `value` to null.
flag.nil();

// All toString(), toJson() operations are passed down to the `value`
print( count ); // calls `toString()` inside  for RxInt

final abc = [0,1,2].obs;
// Converts the value to a json Array, prints RxList
// Json is supported by all Rx types!
print('json: ${jsonEncode(abc)}, type: ${abc.runtimeType}');

// RxMap, RxList and RxSet are special Rx types, that extends their native types.
// but you can work with a List as a regular list, although is reactive!
abc.add(12); // pushes 12 to the list, and UPDATES the stream.
abc[3]; // like Lists, reads the index 3.


// equality works with the Rx and the value, but hashCode is always taken from the value
final number = 12.obs;
print( number == 12 ); // prints > true

/// Custom Rx Models:

// toJson(), toString() are deferred to the child, so you can implement override on them, and print() the observable directly.

class User {
    String name, last;
    int age;
    User({this.name, this.last, this.age});

    @override
    String toString() => '$name $last, $age years old';
}

final user = User(name: 'John', last: 'Doe', age: 33).obs;

// `user` is "reactive", but the properties inside ARE NOT!
// So, if we change some variable inside of it...
user.value.name = 'Roi';
// The widget will not rebuild!,
// `Rx` don't have any clue when you change something inside user.
// So, for custom classes, we need to manually "notify" the change.
user.refresh();

// or we can use the `update()` method!
user.update((value){
  value.name='Roi';
});

print( user );


#### Tests

You can test your controllers like any other class, including their lifecycles:

```dart
class Controller extends GetxController {
  @override
  void onInit() {
    super.onInit();
    //Change value to name2
    name.value = 'name2';
  }

  @override
  void onClose() {
    name.value = '';
    super.onClose();
  }

  final name = 'name1'.obs;

  void changeName() => name.value = 'name3';
}

void main() {
  test('''
Test the state of the reactive variable "name" across all of its lifecycles''',
      () {
    /// You can test the controller without the lifecycle,
    /// but it's not recommended unless you're not using
    ///  GetX dependency injection
    final controller = Controller();
    expect(controller.name.value, 'name1');

    /// If you are using it, you can test everything,
    /// including the state of the application after each lifecycle.
    Get.put(controller); // onInit was called
    expect(controller.name.value, 'name2');

    /// Test your functions
    controller.changeName();
    expect(controller.name.value, 'name3');

    /// onClose was called
    Get.delete<Controller>();

    expect(controller.name.value, '');
  });
}
Tips
Mockito or mocktail

If you need to mock your GetxController, you should extend GetxController, and mixin it with Mock, that way

class NotificationServiceMock extends GetxController with Mock implements NotificationService {}
Using Get.reset()

If you are testing widgets, or test groups, use Get.reset at the end of your test or in tearDown to reset all settings from your previous test.

Get.testMode

if you are using your navigation in your controllers, use Get.testMode = true at the beginning of your main.

Breaking changes from 2.0 #

1- Rx types:

Before After
StringX RxString
IntX RxInt
MapX RxMap
ListX RxList
NumX RxNum
DoubleX RxDouble

RxController and GetBuilder now have merged, you no longer need to memorize which controller you want to use, just use GetxController, it will work for simple state management and for reactive as well.

Why rxget? #

1.	Reliability through simplicity.

After Flutter updates, many packages break due to dependency conflicts or version mismatches. rxget minimizes this risk by focusing on just two core features — reactive state management and dependency injection. With fewer dependencies and no routing or UI helpers, maintenance becomes painless. Update rxget, and you’re ready to build again without worrying about compatibility issues.

2.	Flutter made simpler.

Flutter is great but can sometimes feel verbose. rxget keeps things simple and expressive. You can turn any variable reactive with .obs and use Obx to automatically rebuild widgets. No boilerplate, no complex setup — just reactive code that works seamlessly. 3. Performance without overhead. rxget removes the extra layers found in larger frameworks. It manages memory efficiently, ensuring unused dependencies are disposed of automatically. You write less, focus more on logic, and still get optimal performance with minimal resource usage. 4. Clean decoupling. With rxget, business logic and UI stay truly separate. Controllers can initialize data, perform async work, and update reactive variables — all without depending on the view’s context. This creates a cleaner architecture where UI developers and logic developers can work independently while keeping everything reactive and synchronized.

In short

rxget brings you the essence of GetX — reactivity and DI — without the noise. No routes, no snackbars, no context gymnastics. Just clean, reactive, and efficient Flutter development. This library will always be updated and implementing new features. Feel free to offer PRs and contribute to them.

Community #

Community channels #

GetX has a highly active and helpful community. If you have questions, or would like any assistance regarding the use of this framework, please join our community channels, your question will be answered more quickly, and it will be the most suitable place. This repository is exclusive for opening issues, and requesting resources, but feel free to be part of GetX Community.

Slack Discord Telegram
Get on Slack Discord Shield Telegram

How to contribute #

Want to contribute to the project? We will be proud to highlight you as one of our collaborators. Here are some points where you can contribute and make Get (and Flutter) even better.

  • Helping to translate the readme into other languages.
  • Adding documentation to the readme (a lot of Get's functions haven't been documented yet).
  • Write articles or make videos teaching how to use Get (they will be inserted in the Readme and in the future in our Wiki).
  • Offering PRs for code/tests.
  • Including new functions.

Any contribution is welcome!

3
likes
0
points
92
downloads

Publisher

unverified uploader

Weekly Downloads

A lightweight reactive state management and dependency injection library for Dart and Flutter — pure and minimal.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_web_plugins, web

More

Packages that depend on rxget