Flutter is designed to develop cross-platform applications. Its primary focus is to make user interface (UI) implementation as intuitive as building LEGO.
Other tasks like state management, dependency injection, persistence, and mapping network objects, have to be managed by the developer. However, Flutter’s enormous community makes this job easier and more efficient, continuously working on useful, high-quality packages. They are available on Dart’s official package repository – pub.dev
In this article, I’ve collected ten packages that I’ve found particularly useful during my experience with Flutter.
High refresh rate displays have been all the rage these years.
Utilizing the smoothness and fluidity of a 120Hz display comes at a cost: the smartphone needs to render twice as many frames, hence draining more battery.
Some smartphone manufacturers (e.g., Oppo and OnePlus) try to combat this by maintaining a whitelist of apps to run at 120Hz by default. These systems limit all other apps to 60Hz unless the application itself explicitly asks to be run at a higher framerate.
The Flutter framework has no built-in method to allow this, so flutter_displaymode was born. This package tells the platform to run the app at the highest refresh rate available.
This package, however, is a temporary solution, and the Flutter team is already working on developing an official method to combat this issue: flutter.dev/go/variable-refresh-rate.
Most applications have to store sensitive data, for example, a web token for authentication. A simple file-based database or shared_preferences can be hijacked by other malicious applications on the device, and the user’s login session can be compromised.
A package called flutter_secure_storage offers a simple solution to this problem. It uses Keychain on iOS and KeyStore on Android devices to ensure that all stored data is encrypted and accessible only to your application.
For a large amount of data, it is recommended to generate and store an encryption key in flutter_secure_storage and then use this key to encrypt/decrypt files on the device. This technique has fewer limitations while maintaining security. A guide can be found here. Another package called flutter_secure_file_storage aims to hide this complexity, offering a simple API while still working with flutter_secure_storage under the hood.
You may have been in a situation when you had to reuse your app code to build a similar application with minor changes for a different environment. In-app changes (e.g., different Flutter theme) can be implemented using the --dart-define
command-line argument or relying on environment-based configuration files. However, these methods are limited to Dart and cannot change native settings such as the app’s name, icon, splash screen, bundle ID, and Firebase project configurations.
flutter_flavorizr solves these problems. It allows developers to create a different native configuration for each flavor (i.e., variant) of the application.
After defining a simple YAML configuration and running the utility in command line, Flavorizr makes all the necessary native configuration changes and generates Dart files for each defined flavor. This process will override and modify many project files, so commit all your changes each time before running this utility.
Although Flutter is a cross-platform framework, building native apps can be challenging. iOS and Android users are used to their ecosystem and expect newly installed apps to look and feel the same. Of course, Flutter itself adopts a number of these platform-specific behaviors, but to build an entire app with a native-looking UI on both Android and iOS, we need to utilize two separate widget libraries: Material for Android and Cupertino for iOS.
The flutter_platform_widgets package helps to avoid unnecessary work by combining these libraries into a single selection of platform-aware widgets. It allows developers to define each widget only once. Thus there is no need to have separate widget trees or repeat if-else statements when developing for multiple platforms.
swagger_dart_code_generator is one of those packages that greatly accelerates workflow. This package takes an OpenAPI / Swagger JSON specification and generates all necessary models, mappers, and clients to use that API. It also supports generating clients for multiple specification files and has many configuration options.
jiffy is a Flutter date-time package inspired by momentjs. It offers way more functionality than the built-in DateTime class, including parsing from and formatting into custom date-time formats, doing operations between dates, and even printing out relative time like “5 hours ago” or “in 2 days”.
Making icons for Flutter apps used to be a long, tedious process, having to get an image with exactly the right size, upload it to a tool like appicon.co, and then manually copy all the icons to the right places, making sure not to mess up any folder or filenames.
The flutter_launcher_icons tool takes one image located anywhere within your project and generates launcher icons and the related configuration files for both iOS and Android. All it takes is one png, a few lines of YAML, and running a single command.
Do you frequently use Font Awesome, Material Icons, or other icon packs?
Inspired by the popular react-native-vector-icons, the flutter_font_icons package bundles 15 different icon packs, containing 13413 free-to-use icons, so you’ll never have to spend time looking for icon packs on pub.dev again.
To put an about section in your app, displaying the current app name, version, build number, and other helpful information, you can use package_info_plus to get all of that information in your project.
Do you ever find yourself having way too many packages in your pubspec.yaml file?
It’s easy to try out a package and then forget to remove the dependency from the project. Or maybe you used a package in the project but haven’t added it to the pubspec file, so it’s merely being pulled in as an indirect dependency by something else. These undeclared dependencies can cause problems with your build later on.
dependency_validator aims to solve such issues: it analyzes the project and reports which dependencies are undeclared and which ones could be safely removed.