Updating your pub package to Dart 2
Dart 2 is imminent. If you own a package on pub.dartlang.org, you might want to make sure it’s ready.
Head over to pub and search for packages associated with your email. If you’ve been around the Dart ecosystem for a while (like me), you might have forgotten about ever writing some of these.
If you go to pub.dartlang.org and search for
email:email@example.com, you’ll see all the Dart packages you own.
Decide which ones are worth updating
Some packages are timeless, and some not so much. For example, my
simple_preprocessor package for adding C-style macros can safely die in Dart 1 land. It was useful at some point, but only to me, and not any more. Pub does a decent job of hiding these old packages from users, sorting them at the very bottom of everything. (In the future, we might add the possibility for package owners to flag their own packages with the [DEPRECATED] flag.)
Pub now helpfully scores every package, and one of the criteria is popularity. If your package has popularity > 0, then it’s definitely being used by people other than you, and it’s worth updating.
Install Dart 2 (and 1)
If you’re using Flutter, you already have a preview release of Dart 2 (in
$YOUR_FLUTTER_PATH/bin/cache/dart-sdk/bin/dart). But that's version
2.0.0-dev.58.0 so I recommend that you install the latest one via the standalone Dart SDK process. As of this writing, that will give you version
I found it useful to keep Dart 1 around. You can do that via homebrew’s
switch command, but that's assuming that you still have Dart 1 in your homebrew cache — and it's also quite annoying to switch from one version to another all the time. So, if you're like me, you'll just go to the manual download page, download the latest Dart 1 SDK as a zip file, unzip it somewhere, and then make an alias like this in your
This lets you freely switch from running things in Dart 1 world and Dart 2 world. You should be able to do this now:
$ dart --version
Dart VM version: 2.0.0-dev.69.1 (Fri Jul 20 18:30:52 2018 +0200) on "macos_x64"
$ dart1 --version
Dart VM version: 1.24.3 (Wed Dec 13 23:26:59 2017) on "macos_x64"
1.24.3 will likely be the last version of Dart 1, so I feel it's okay to install it manually like this.
Migrate the code
There’s a migration guide here: dartlang.org/dart-2. Go read it, it has really useful bits of information, like the existence of the
dart2_fix tool, the
dartfmt --fix flag, and many more.
If you haven’t touched your package in a while, a common set of things to do first is:
- Bump the SDK version constraints in
pubspec.yamlfrom something like
sdk: ">=1.8.0 <2.0.0"to something like
sdk: ">=2.0.0-dev <3.0.0"(or
sdk: ">=1.24.3 <3.0.0"if you want to keep Dart 1 compatibility)
- Bump all
pubspec.yamlto Dart-2-compatible versions (check their change log to find the version). Avoid pinning dependencies to the very latest version unless you absolutely need to. Having a broader range will give you package users more freedom to pick their own dependency versions.
pub upgrade(not just
pub get). Even better, run
_PUB_TEST_SDK_VERSION=2.0.0 pub upgrade(explained here).
Then you’re ready to fix errors, if any. This is where the Dart 2 migration guide (linked above) is helpful, with pages like Fixing Common Type Problems.
When you have no more errors but still have warnings, don’t forget that you can use
dartfmt --fix (again, see the helpful migration guide linked above) to get rid of the lints and warnings automatically.
dart2_fix deals with changes to constant names (like
dartfmt --fix removes unnecessary
const. Don't do it yourself when you don't need to.
What’s left after this step are mostly deprecation warnings. For example, instead of
int.parse(string, (_) => -1), you now do
int.tryParse(string) ?? -1. Integers are now 64-bit, so if you want really really big numbers, you need to use the new
BigInt class. That kind of thing.
Optional: add CI testing
You create a new file in the root of your package called
.travis.yml and fill it with something like this:
- dartanalyzer --fatal-warnings --fatal-lints .
- pub run test
You need to tell Travis to use the
dev version of Dart (i.e. Dart 2) for now because by default it uses
stable (which is, as of this writing, still Dart 1).
Once Dart 2 lands, you might want to change this back, or use Travis’s build matrix to test on various versions.
By the way, the
script: part isn't necessary. It's useful if you want to prevent code with warnings or lints from ever reaching your repo. If you're not that hardcore, leave that out. Travis will run
pub run test for you.
(There’s more you can do in your
.travis.yml file. Read the Travis Dart docs here.)
Once you have the
.travis.yml file set up, go to your Travis profile, enable Travis for this particular repository, then push your changes (including the
.travis.yml file). If you're like me, you won't make it quite right on the first few tries. That's okay, just keep at it until Travis runs and the result is green.
Then, take the badge and put it in your
README.md. You earned it. (And potential users of your package will find it super useful.)
Oh, and do make use of Travis’s awesome “cron job” functionality. It’ll rerun your test every day/week/month for you even when there’s no change on your repo.
Add a change log
While we’re at this, add a
CHANGELOG.md file (assuming you don’t have it yet). Take this as a fresh start and just add the first record for this change, i.e. something like this:
- Upgrade to Dart 2
Bump your own version
If you only made some small internal changes, and no changes to your API, you can bump just the minor version. (At least that’s my reading of the semver spec.)
But do feel free to bump to the next major version. Especially if you’re not yet v1 (e.g. your version is something like
0.1.3) and yet there are people building software on top of your package. This is as good an excuse as any to release a stable version.
Upload to pub
Now wait a few minutes and review the package’s page on pub.dartlang.org. It should get a better score, but — more importantly — it’s now ready for Dart 2.