Skip to main content

Flutter packages

These are the packages that I use in the majority of applications, and I'm pretty happy with them.


Flutter navigation package, it allows for strongly-typed arguments passing, effortless deep-linking and it uses code generation to simplify routes setup, with that being said it requires a minimal amount of code to generate everything needed for navigation inside of your App.


The main advantages of this library:

  • it generates code for routes, so that you have compile-time safety for page arguments;
  • it has a decent support for nested routing.

Unfortunately, the documentation is pretty poor and some behavior can be confusing.

bloc + bloc_concurrency + flutter_bloc

BLoC pattern implementation + Flutter-specific widgets.


There are some discussions about whether to use BLoC as a part of business logic, or as a presentation logic (kind of ViewModel). For me, this library is not about "state management", but rather a FSM (Finite State Machine) pattern implementation.

That means, it can be used whenever this pattern seems to be suitable: most often, as an app logic holder, sometimes as a presentation logic holder (although, in general, I'm against ViewModel pattern in Flutter, sometimes it can be useful).


Contains utility functions and classes in the style of dart:collection to make working with collections easier.


Allows computations on decimal numbers without losing precision like double operations.

dio + retrofit

retrofit.dart is a type conversion dio client generator using source_gen and inspired by Chopper and Retrofit.


If you have experience in developing native Android apps, you’ve probably heard about the Android retrofit library that served as inspiration for this package. The idea is that you’re defining an interface with methods communicating with backend API, then the library generates the bodies of those methods, taking care of the serialization/deserialization of request and response DTOs.


Reactive persistence library for Flutter and Dart, built on top of sqlite.


Immutable collections.


Code generator for immutable data classes, unions etc.


Immutable objects are easier to deal with. You cannot accidentally change them, so they can be freely passed by as arguments. Sealed classes provide a nice feature of "limited" inheritance. Built-in support for serialization (implemented with json_serializable).


Automatically generate code for converting to and from JSON by annotating Dart classes.


This is the most popular library for JSON serialization and deserialization.


A wrapper around InheritedWidget to make them easier to use and more reusable.

These are the packages that are pretty popular and recommended by many developers, but I personally find them rather anti-patterns and advise to avoid in production code.



It provides implementation of == and hasCode methods based on the provided list of properties, but there are problems:

  • it doesn't require classes to be immutable;
  • it relies on the manual implementation of props (the number of properties to take into account for equality check), which is error-prone.



Two main problems with this package:

  • this is React concept, it's not Flutter way;
  • it breaks the convention of build being a pure function free from side-effects.

Again, author tries to hide some "complexity" of pretty important Flutter concept: stateless vs stateful widgets and their lifecycles, bringing more confusion and some pitfalls.



The idea of a framework inside another framework seems weird enough already. GetX introduces a lot of unnecessary abstractions and tries to "hide" the complexity of the Flutter (introducing its own complexity instead). Also, the code quality is pretty low.



Despite the author claiming riverpod to be the successor of provider, they are totally different: provider is just a wrapper over InheritedWidget – thing you need to know anyway when dealing with Flutter. provider just gives you convenient extensions and classes to reduce the boilerplate. riverpod is a "parallel" implementation of the same functionality that again tries to hide some "complexity" of the Flutter (obscuring some pretty important Flutter concepts, such as widget lifecycles).