Achieving Flutter Favorite Package Quality
This article doesn’t show you how your package become a Flutter Favorite package, it rather shows you how to meet and exceed the quality bar for the Flutter Favorite program.
About the author:
Jonas is a Dart & Flutter GDE as well as a Flutter Favorite package author. His Flutter Favorite package is feedback.
But first, what is a Flutter Favorite?
The aim of the Flutter Favorite program is to identify packages and plugins that you should first consider when building your app. This is not a guarantee of quality or suitability to your particular situation — you should always perform your own evaluation of packages and plugins for your project.
— Flutter Favorite Page
You can see the complete list of Flutter Favorite packages on pub.dev.
Flutter Favorite packages have to meet a certain quality, this quality is measure based on the following metrics
- Overall package score
- Permissive license, including (but not limited to) Apache, Artistic, BSD, CC BY, MIT, MS-PL and W3C
- GitHub version tag matches the current version from pub.dev, so you can see exactly what source is in the package
- Feature completeness — and not marked as incomplete (for example, with labels like “beta” or “under construction”)
- Verified publisher
- General usability when it comes to the overview, docs, sample/example code, and API quality
- Good runtime behavior in terms of CPU and memory usage
- High quality dependencies
Let’s take a look at each individual metric and see how we can achieve to meet, but, ideally, exceed the quality bar.
Package Score
The package score is a metric which in turn measures various metrics on its own.
The first one is ‘Follow Dart file conventions’. In order to achieve all
available points, you have to use a permissive package license. This
means to use an OSI-approved license. To learn more about licenses, you
can take a TLDRLegal which explains licenses in plain English.
A list of OSI-approved licenses can be found at
https://opensource.org/licenses/. Additionally, you
have to provide a valid README.md, CHANGELOG.md and pubspec.yaml file.
This can be checked via dart pub publish --dry-run
.
The next category is ‘Provide documentation’. To get all available points, you have to provide extensive documentation, including an example. To make sure that all your APIs are documented, you can turn on the following links:
The Dart doc side tells you how you should structure your example.
The ‘platform support’ metrics grants you full points, when you support all platforms that Flutter supports. This is only important, if your package is platform specific.
‘Pass static analysis’ means that you should have no warnings or errors
when running dart analyze .
or dart format .
. Ideally, you should
also use lints or
flutter_lints.
‘Support up-to-date dependencies’ grants all points, if your code works when using the newest available dependencies listed in your pubspec.yaml file, and also supports the latest Dart or Flutter version.
GitHub version tag matches Pub version
To be clear, this doesn’t mean that you have to use GitHub, GitLab and other git hosts are also fine, but your git tags should still match the versions on pub.dev. The aim of this rule is that people can easily see what code is in which version. This aims to raise confidence against supply chain attacks.
Ideally, you automate this by deploying your code to pub.dev, when you create a new version tag. If you’re indeed using GitHub, you can use the guide from the Dart team to automate publishing.
Verified Publisher
By being a verified publisher, you’re letting your consumers know, that you’ve verified the identity. For example, dart.dev is the verified publisher for packages that Google’s Dart team supports. Again, this aims to raise the confidence in you being a trustworthy publisher and thus supply chain attacks are less likely.
To become a verified publisher, you have to follow the guide from the Dart team.
Usability of docs
Additionally, to the tips for docs further above, you should put a lot of care into your docs, so that they are helpful. This means you should give code snippets which show the consumer how to use your library. These code snippets should have an explanation telling the consumer why it works that way.
Packages that set a good example are
Runtime behavior and dependencies
Further requirements are
- Good runtime behavior in terms of CPU and memory usage
- High quality dependencies
Usually, if you don’t do anything stupid, your code will not behave bad and thus has a good runtime behavior and a good performance. If you’re in the unfortunate situation where your package does a poor job, you can use the Dart Dev Tools to debug that problem. Good resources for that are the pages about the performance tools, the CPU profiler and the memory profiler.
Ideally, your package doesn’t have any dependencies, as dependencies are costly. Of course, there are cases where it’s necessary. In those, you should make sure to use dependencies which use a compatible license (as already discussed above) which have a high number of pub points, a high popularity and tests. Typically, those dependencies are already battle tested and thus of a higher quality.
Implied package aspects
There are some other aspects you need to consider next to the explicitly stated quality properties.
Those are for example that your package should already have a high popularity, since that is already an indicator that you match at least a few of the above stated properties. Furthermore, your code should be well tested in a sensible way, so like widget and golden tests for widgets, unit test for non-UI code or integration test for native platform code.
Originally published on Medium.