Material 3 + Flutter 3.16.0 Broke Pi Garage Theme

What happened?

The release of Flutter 3.16.0 introduced something that caught me out and broke the theme in the Pi Garage companion mobile app.

Although Material 3 has been “opt in” for quite a while (I couldn’t find since when) it is only in 3.16.0 breaking changes https://docs.flutter.dev/release/breaking-changes/material-3-default you can see that this version has flipped the default value for the flag (useMaterial3) from false to true.

In the Pi Garage mobile app I did not set this flag to false when it was introduced as well as I didn’t lock the version of Flutter in the GitHub action that built and deployed the Android and iOS apps.

During the V2 of Pi Garage development I did not upgrade flutter on my local dev machine when Flutter 3.16.0 was released. This meant that in my local environment I was using 3.13.0 and my local testing worked however when the production version was published to the App Stores it was using 3.16.0 and was using Material 3 instead of Material 2. An emergency fix was released with the flag set to false to disable Material 3 however there was a time when the mobile apps had a unpredictable UI experience.

Always Pin Dependency Versions

Pinning dependencies to specific versions can be a “double edged sword”. On one hand you get the safety that things will not change without expressly however on the other side you may have some developer machines that are not in sync with critical dependencies. In all production applications you should do the former to avoid such surprises.

This might have you thinking why didn’t I have this already pinned. The answer is that for this small personal project just getting the apps built and deployed in an open source CI pipeline (GitHub Actions) was already hard enough and I just didn’t.

Backwards Compatibility Thoughts

The semantic versioning spec lists that for the feature/minor (middle number) it defines it as below.

MINOR version when you add functionality in a backward compatible manner

From semantic versioning spec.

This makes me question the decision on “flipping” the logic for the Material 3 flag. I understand that having a flag to allow you to turn it off and revert the previous behaviour of Material 2 does technically allow you to be backwards compatible but it does make you think about the longevity of this flag.

For example will it eventually be deprecated and removed in a 3.X release? This would break the minor spec. For reference the major spec is quoted below.

MAJOR version when you make incompatible API changes

From semantic versioning spec.

My personal feelings is that the optional (defaulting false) flag to include Material 3 is valid semantic versioning. I would have done this myself to allow developers to start using new functionality as well as finding/fixing bugs. This is especially important for large pieces of work and I think that including Material 3 fits this description.

However I feel that doing the switch on the logic for that flag should not have been included in a minor/feature release. Personally when the project would be ready to make it the default I would just flip the logic and release version 4.0.0. This sends a clear message that there is a breaking change to be aware of to consumers of a library. Consequently I would then release version 5.0.0 that would remove Material 2 entirely (or at least you couldn’t enable it but the code may remain there whilst you remove it on a piece meal basis).

At the end of the day whenever you write a library that is going to be consumed by others it is important to be clear in what your feature set that you support is for a given version and what is new/deprecated/modified. Developers should not be afraid of increasing version numbers to make clear deliberate and intentional API changes.


Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *