19 rules when publishing a Dart package

Alexey Inkin
Flutter Senior
Published in
7 min readAug 14, 2022

There is a great guide on publishing a Dart package: https://dart.dev/tools/pub/publishing

Here is my checklist on top of that. Every mistake here I made at least once, and that costed me another published version. Publishing is free, but I feel guilty wasting the eternal storage of pub.dev.

So here is the checklist, and then the details:

1. Start at version 0.1.0.
2. Prefer repository over homepage in pubspec.yaml.
3. Description length is between 60 to 180 characters.
4. Add an example.
5. Proofread Markdown files.
6. Generate the Table of Contents
7. Add analysis_options.yaml.
8. Format interactively.
9. Create .pubignore if you have example images.
10. Commit all changes with -dev version, and push
11. Run dart pub publish -n, check errors.
12. Remove temp files.
13. Drop -dev from the version.
14. Publish.
15. Run git status.
16. Add the version to the commit message.
17. Add the version tag.
18. Push everything to git.
19. Check how the package looks on pub.dev.

Start at version 0.1.0

The Flutter package template is generated with version 0.0.1. However, semver suggests version 0.1.0 as your first one. I follow this because:

  • 0.1.0 looks more assuring than 0.0.1.
  • 0 at the end indicates that this is the first attempt at some new development, not a fix, and I like the first version to be consistent with this.

Prefer repository over homepage in pubspec.yaml

The Flutter package template suggests using homepage field. I replace this with repository field.

On pub.dev, this is shown as a link. It used to show “Homepage” if you put your repository to homepage field, so it was important to use repository for it to be displayed as “Repository (GitHub)”, which looks more assuring.

Nowadays pub.dev recognizes a GitHub repository in homepage, so there is no visible difference. But it may be important if you decide to use both. And a repository in the repository is just the proper way to do things. It has a tint of domain-driven development in it.

Description length is between 60 to 180 characters

If you violate this, there is no warning at publishing, but your package rating suffers:

If you want a warning on this, thumb-up the issue that suggests this.

Add an example

There is no warning if you publish a package without an example, but it impacts the rating of your package:

See here for what is recognized as an example by pub.dev.

Proofread Markdown files

You normally only see mistakes in Markdown when you publish, because they are hard to spot in a raw file. So to save commits and publications, you should proofread.

I use ReText for this:

Unfortunately, it does not show images hosted on GitHub, does not highlight embedded code syntax, and is generally poorly made, like it does not show icons on buttons on my default Ubuntu installation with apt-get, the way that should be tested the most.

Tell me in the comments what preview tool you use for Markdown.

Generate the Table of Contents

For large files, I also generate a table of contents with this tool:

Add analysis_options.yaml

IDEs create analysis_options.yaml for you. But if you created the project outside of an IDE, you should add this file yourself. There is no warning if you publish without this file, and the pub.dev server will use the default file to analyze your package, which depends on Dart version, and so the result is inconsistent.

The default analysis_options.yaml is as simple as this:

include: package:flutter_lints/flutter.yaml

I use my own package total_lints in my projects. It has a separate rule set for publishable packages that is very strict.

Format interactively

There is no warning if you are publishing a package that does not match the dart formatter, but it hurts the rating of your package.

The formatter can fix the files automatically for you, but often you can improve readability by playing with trailing commas, variable name length, etc.

So run this:

$ dart format -o none lib test

This will show files that are not formatted well but will not fix them, that is what -o none is for.

Then open each file individually and format it with the IDE (Ctrl-Alt-L in Android Studio). This way you can Ctrl-Z if the formatter has spoiled something for you.

Create .pubignore if you have example images

.pubignore works like .gitignore, but it prevents files from being published. Read this for more.

If you have images in your README.md, they are useless on pub.dev and do not show if referenced by a relative path.

The common way to show images on pub.dev is to have them in your GitHub repository, and then include them in README.md like this:

![Description](https://raw.githubusercontent.com/alexeyinkin/flutter-app-state/main/img/multiple-stacks.gif)

This does not concern images in your assets. Publish them normally. Otherwise, they will not be accessible to users.

Commit all changes with -dev version, and push

You should push your changes before publishing. This will allow you to:

  1. Run GitHub workflows to detect issues.
  2. See mistakes in Markdown in README.

But what version should be in pubspec.yaml in your commit? It should not be any stable X.Y.Z, because technically that commit will not match any published version. A good idea is to label it X.Y.Z-dev, where X.Y.Z is the next stable version you aim to publish.

On this step and on, various tools will be reporting issues to you. It is important to commit frequently as you will be fixing them. Otherwise, you can publish the package but forget to commit that exact state, and do some edits after that. You will then have a hard time getting your code back to the published state in case you need to.

If you do not have the CI or doing trivial changes, you may skip pushing intermediate commits and keep amending a single commit to keep the history cleaner.

Run dart pub publish -n, check errors

Run dart pub publish -n in your package root and examine any hints. -n is to run the checks but not publish.

It should break if you don’t have LICENCE. It should warn you if you have any analyzer issues, or don’t have CHANGELOG.md, or README.md, or have forgotten to add the current version to CHANGELOG.md, and on some other issues.

Note that some issues are not reported until the real publishing, like a duplicate version. For this reason, you should not label any commit with a stable tag until you really publish the package.

Remove temp files

Even if you do not commit your temp files, they still get published to pub.dev, because it has nothing to do with git, and it is easy to forget this.

dart pub publish -n shows you the tree of files to be published. Examine that tree.

Drop -dev from the version

When your CI runs smoothly, and dart pub publish -n shows no issues, remove -dev from your version number.

Publish

Run dart pub publish and confirm.

Run git status

Run git status to double-check that you have committed all the fixes you made when publishing. Commit everything that is missing.

Do not amend anything even if you had published the package with some mistakes. A commit at your git tag should exactly match what is published on pub.dev for better maintenance.

From this point on everything you can edit is the commit message.

Add the version to the commit message

If you have not done this before, amend your prepared unpublished commit to add the version in the form of , v0.2.0 at the end of the message, like

Bump version, v0.2.0

This allows you to locate the commit using git log command.

Add the version tag

Run git tag v0.1.0 to add the tag. This allows you to check out any previous version with git checkout v0.1.0.

You can also list your tags with git tag:

$ git tag
v0.1.0
v0.1.3
v0.1.4
v0.2.0
v0.2.1
v0.3.0
v0.3.1

Push everything to git

$ git push
$ git push --tags

Check how the package looks on pub.dev

  • Read the README.
  • Check the images and links.
  • Check if the license is recognized as a slug like “MIT”, “BSD-3-Clause”, etc.
  • Check if all six platforms are recognized (or less if that was your design).
  • Check the score when it becomes available.

GOTO START if there is anything you don’t like

Do not feel guilty if you have published a version with a mistake and have to publish a new one right away. It is more important to carry your message to the potential users who otherwise will settle with another solution that does not fit their needs as well as yours.

--

--

Alexey Inkin
Flutter Senior

Google Developer Expert in Flutter. PHP, SQL, TS, Java, C++, professionally since 2003. Open for consulting & dev with my team. Telegram channel: @ainkin_com