I am wondering how Dart package versions are resolved in my Flutter application.
Say, I have a dependency
foo and declare a dependency like this:
How does Dart Pub know what version to resolve / what happens when a new version is available?
Furthermore, if I want to publish my Flutter plugin to pub.dev, how do I decide when to increase what part of the version?
Dart package versioning
All of this goes back to Dart package versioning, i.e. there is no distinction for Flutter plugins.
It is based on
SemVer 2.0.0-rc.1 (Semantic Versioning). For Dart packages, the gist of the covention is as follows:
Note that Pub also supports pre-release versions denoted by:
Example versions might be
0.6.0-nullsafety.0 (with a patch version of
To get a basic understanding of what problem the version resolving tries to solve, you can read through the Resolving shared dependencies section of Dart’s package versioning article. The aspect of version resolving that I will look at here is the caret syntax.
^ syntax is the standard syntax for resolving versions in Dart and closely connected to the versioning tables above. Whenever you define a dependency using
foo: ^1.0.0, there is a bit of logic involved to determine which versions can be resolved from that string.
^ matches up to major versions. This means that whenever you have a breaking change in your API, you will want to bump the major version because then dependants will not automatically be upgraded to your next package version. I will try to illustrate the matching in a table again:
As you can see, caret syntax will match any version that is greater than or equal to the current version but smaller than the next major version.
Note that pre-release versions are handled differently than normal (not exactly according to the SemVer spec) in Dart. You can find the source code for Pub’s
pub_semver tool on GitHub. It declares that pre-release versions are not matched by the caret syntax (and neither by the traditional syntax):
I quickly want to mention the role of the Pubspec lock file for dependency resolving in Dart.
There is a straight-forward way that I think defines how package versions are fetched:
pub getwithout an exiting
pubspec.lock(initial fetch) will fetch the latest possible versions (according to above rules and satisfying all direct and transitive constraints of shared dependencies).
pub getwith an existing
pubspec.lockfile will prefer the locked versions in the lock file over latest versions (if they still satisfy constraints by potentially newly introduced dependencies since the last fetch).
pub upgradethrows away the existing
pubspec.lockfile and then acts the same way as the initial
pub get in your app will not unexpectedly fetch new versions. And when working with colleagues, everyone will fetch the same versions according to the
pubspec.lock file when running
pub get and having included the lock file in version control.
Because the Dart team recommends some best practices for versioning, I want to make sure to include them in here directly:
Use caret syntax
Specifying dependencies with version ranges is such as
^1.6.3is a good practice because it allows the pub tool to select newer versions of the package when they become available. Also, it places an upper limit on the allowed version, based on an assumption that packages use semantic versions, where any version of path versioned
1.xis compatible, but where a new version
2.xwould be a major upgrade that isn’t semantically compatible with
Depend on the latest stable package versions
pub upgradeto update to the latest package versions that your pubspec allows. To identify dependencies in your app or package that aren’t on the latest stable versions, use
Test whenever you update package dependencies
If you run
pub upgradewithout updating your pubspec, the API should stay the same and your code should run as before — but test to make sure. If you modify the pubspec and update to a new major version, then you might encounter breaking changes, so you need to test even more thoroughly.
Answered By – creativecreatorormaybenot
Answer Checked By – Robin (FlutterFixes Admin)