Reliably removing deprecated code on a scheduled basis.
A new year is approaching, and on the Flutter team, we’re getting ready for a clean start to 2021.
In preparation, we’re going to remove some of the deprecated APIs in the Flutter framework.
Removing deprecations in the Flutter framework isn’t new. I’ve done it myself in the past. A quick search shows that deprecations were removed without a defined timeline or schedule because our deprecation policy doesn’t stipulate when to remove them. Because we want to provide a consistent and reliable experience for our users, we decided to create a standard lifetime for deprecations.
This article discusses our current policies for breaking changes and deprecations, how they’re put into practice, and how they’re evolving to provide a better experience to our users.
Breaking changes in Flutter
The process for deprecating code in Flutter begins with our breaking change policy. Deprecations are considered breaking changes, which means that they must follow the public design document guidelines which requires a period for discussion. (The design document for this proposal is Implementing a Lifetime for Deprecations.) In addition to providing a design document, we reach out on the Flutter Contributor Discord and popular groups like flutter-announce and flutter-dev, all before making any changes. This is one of my favorite parts of the process as an engineer: I get to hear from you. Our wonderful community is incredibly engaged with this process, and we are better for it. On multiple occasions, I’ve seen the design of a feature improve greatly — all thanks to feedback from our community — after publicizing it through these channels.
Authors of breaking changes migrate customer code affected by a breaking change. In the last update to our breaking change policy, we invited you to submit your tests to our customer test repo. These tests are our signal that a change is breaking, and we are committed to working with the test authors to migrate their code before making the change.
We also provide migration guides for our breaking changes. These guides are intended to help users migrate their code after updating to the latest version of Flutter. If you’ve seen one of our release announcements, we also call out breaks in a given release, and we point users to helpful resources for updating their applications.
In a past survey, we asked users about their preferences for breaking changes. We learned that our users thought breaking changes made code cleaner and were valuable to them, which is why we usually prefer a breaking change over a deprecation. According to the study:
Overall, 78% said that they prefer breaking changes that result in the cleanest possible API; this also makes the API easier to learn and use.
Our breaking change policy is based on this study. As always, there are exceptions to every rule. I recently deprecated some very popular methods in favor of a new widget. If we know a particular change is a significant break that affects many users, we’ll deprecate. Deprecating allows for a migration grace period, while still providing all of the tools generated by the breaking change policy.
The migration grace period begins when the deprecation is released on the stable channel. The timeline for when the grace period ends is 1 calendar year or 4 stable releases, whichever is longer. In order to come up with a timeline that we thought was comfortable, we looked at our growth and adoption, and we evaluated some of the Flutter applications and packages that are open sourced.
We want our users to be able to count on this schedule, rather than wondering if the next release will bring an unexpected barrier to upgrading because a deprecation disappeared. We also want to make sure that we communicate these changes well ahead of time, and we commit to announcing deprecations reaching the end of their lifetimes before we start removing them. In that spirit, I’d like to share with you the first batch of deprecations that are reaching their end of life, now that Flutter 1.22 is available.
Because this is the first time that we’re putting this policy into practice, there are quite a few deprecations — some pre-dating Flutter 1.0! Several of these deprecations also pre-date our breaking change policy. We’ll be working on migration tools and guidance for all of them. Expect to see these deprecations removed from the Flutter framework by our next stable release, with announcements occurring in our usual channels as they’re removed.
While we get underway implementing these changes, we hope to hear from you! We’re always accepting submissions to our customer test repo where we work with you to migrate your code before making a break. To learn more about the test repo and how to submit your tests, take a look at the Flutter tests README. As we make these changes, we’ll use the Flutter Contributor Discord, flutter-announce, and flutter-dev channels to notify you and request your feedback. So, if you haven’t joined one of these groups, please do! We look forward to hearing from you and working together.