Pinned Flutter dependency versions

One of the biggest pain points for package authors (and probably app developers too) that have been brought up during the Dart & Flutter Package Ecosystem Summits is that Flutter has pinned versions of its dependencies.

Why do we not want pinned dependencies? Because it leads to a lot trickier dependency version resolution for the end user than what it needs to be. I would say almost all Flutter developers have at some point ended up in dependency resolution hell, before they realize that some dependencies needs to be treated with special care.

Since all of the pinned dependencies are controlled by Google it should be fairly straight forward to set up a process so that they all have some tests towards Flutter before doing a new non-breaking release or doing deprecations.
The main ones are: intl, meta, collection path, vector_math and async.

The Flutter team’s rationale for using pinned versions is outlined in this document. Everyone else is strongly recommended to not pin dependencies though, but the same arguments that are made by the Dart team here should also apply to Flutter.

In the latest drama there were complaints that the Flutter team thought more about what is convenient for them (which I don’t necessarily agree with), instead of the actual end user, to fix this problem I think would very much show otherwise!

What do you think needs to be done (technically) for us to not have pinned dependencies in Flutter?

5 Likes

Personally I had some issues with intl being pinned and some other library that I used forcing a different version of that. It was a bit painful to workaround (I think forked the 3rd party library temporarily just to fix it). However, I don’t think I would need this to be loosen for the remaining packages that much.

I think it may all come down to the proper messaging and tooling support. Maybe when browsing the packages in pubspec.yaml there should be an tooltip warning shown or pub get should report it clearly that a given package comes from flutter at a given version etc.

1 Like

We always say that the versioning should strictly follow the semantic version standard so that no breaking will happen when the author bumps minor versions, but for most of the packages, the thing is totally different in my practice. Nowadays I’d recommend app projects to stick along with fixed package versions, while packages should allow packages between patch versions until they’ve verified the new minor version is working.

For packages: foo: '>=x.y.z <x.y+1.0'

That would be great too, and maybe a much easier thing to start with. It’s still only masking the initial problem though, which I think should be solved properly.

Like in Flame for example, if we would start pinning our dependencies, that would be unacceptable. But why is it acceptable when it is done from Flutter’s side? Is it just because we are so used to it? :thinking:

Indeed many packages aren’t that good at following semver strictly, but the Google controlled packages listed above are, so having some pipeline support that checks that Flutter is OK before releasing a new version shouldn’t be that big of a problem. In a few instances there have been minor breaking changes that have slipped through that should have required a major bump, or deprecations (which according to semver aren’t breaking) that have gone in that have given them headaches, but both those scenarios could have been avoided by a CI job.

Then there is the question of reproducible builds, but that shouldn’t be that hard to solve either, via a temporary lock file used in builds for example.

2 Likes

I just got the news that it actually is on the Flutter team’s radar (although no timeline), I opened up an issue to track it here:

8 Likes