Flutter packages
List of recommended packages
These are the packages that I use in the majority of applications, and I'm pretty happy with them.
auto_route
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).
collection
Contains utility functions and classes in the style of dart:collection to make working with collections easier.
decimal
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.
drift
Reactive persistence library for Flutter and Dart, built on top of sqlite.
fast_immutable_collections
Immutable collections.
freezed
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
).
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.
provider
A wrapper around InheritedWidget to make them easier to use and more reusable.
List of non-recommended packages
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.
equatable
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.
flutter_hooks
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.
get
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.
riverpod
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).