All about the Pub command line tool for Flutter and Dart

Suragch
Suragch
May 31 · 15 min read

There’s so much more than flutter pub get

Modified screenshot from pub.dev

If you’ve been working with Flutter for any length of time, you’ve probably run flutter pub get in the terminal or at least seen a popup about it from your IDE. The Pub tool has a lot more than just get to offer you, though. Pub is the official repository for the Flutter and Dart packages available at pub.dev, and pub is your commandcommande line interface to that repository. This article will introduce the many optionsoptio that are available with the Pub tool.

Overview

Assuming you have a recentune récent version of Flutter and Dart installed and in your path, open a terminal and run the following command to see all the options that pub offers:

The -h means help. You can also use --help instead.

Here is the printout:

The sections below will introduce each of these to you. Feel free to scroll down to the ones that interest you most.

The pub command works with Dart as well. Run the following command:

You’ll see a similarune similaire list:

Only pub, run, test, and version are missing from this list.

You may have seen tutorials that use the pub command directly like so:

This way of using the Pub tooloutil is deprecated now, and you should use it in combination with flutter or dart like so:

If you’re in a Flutter project use the former. Otherwise, for a pure Dart project use the latter.

Project setup

To use some of the Pub commandscommandes you’ll need to be in the root of a Flutter or Dart project that contains a pubspec.yaml file. If you don’t have one available, create a new Flutter project like so:

Then enter the project:

You’re all set! Let’s have a look at the different Pub options now.

version

This tells you the Pub version. Try it out:

The result is:

This is the same as the current Dart version at the timethe time of this writing.

get

You’re probablyprobablement already familiar with this one, but it doesn’t hurt to review. And there’s a goodun bien chance there’s still something to learn.

The get option gets a Flutter or Dart package from the pub.dev repository. This package is just code that other peoplegens have written so that you don’t have to. No need to reinvent the wheel…or an audio_video_progress_bar (shameless self plug).

Every time you start a new projectprojet or clone a repo from GitHub, you need to run pub get in the project root:

If you haven’t done that before, it’s probably because Android Studio or VS Code was doing it for you.

Getting a new package

To see what get really does, let’s add a package. Open pubspec.yaml and add the audio_video_progress_bar package in the dependencies section.

Notes:

  • The two-space indent is important in yaml files. Don’t forget it!
  • You can also delete the cupertino_icons package if you see it there. We aren’t going to use it.
  • I purposefully used an old version of the audio_video_progress_bar package. The current version at the time of this writing is 0.4.0. You’ll see why we’re using the old version in a minute.

Now open a terminal and run the following command in the root of the project:

The pubspec.lock file

Now open pubspec.lock (right next to pubspec.yaml) and search for audio_video_progress_bar. You should find something like this:

Note that the version number is 0.3.2. That’s because you added the ^ in front of the version ^0.3.0 in pubspec.yaml. The ^ tells Pub to get the newest non-breaking version after 0.3.0, which in this case is 0.3.2. This is known as semantic versioning and if you don’t know about that yet, you should definitely learn. You can start with this Stack Overflow Q&A.

Where third-party packages are stored

So Pub got the code for the audio_video_progress_bar. Where is it?

To find out, open .dart_tool/package_config.json in the root of your Flutter project. Then search for audio_video_progress_bar again. You should see something like this:

The rootUri tells right where it is stored on my machine, in the .pub-cache folder. Follow the path and you can see the entire package right there:

Specifying specific versions

When you run flutter pub get, it gets the exact version of the package specified by your pubspec.lock file. To see that in action, open pubspec.lock and change the versionla versio number to 0.3.1 instead of 0.3.2:

Now do another pub get:

Check .dart_tool/package_config.json again and you should see it pointing to a new version:

And navigating to that location with a file explorer will show the newly downloaded folder:

Both versions of the package are in the Pub cache, but your project is using version 0.3.1 now.

So why is all that useful? Well, if you include your pubspec.lock file when you share your project with other people, they will get the exact same dependencies as you when they run flutter pub get. That makes it a lot easier to ensure the same behavior.

upgrade

Unlike flutter pub get, the update command doesn’t use the specific package version from pubspec.lock. It gets the newest non-breaking version based on the pubspec.yaml settings and then updates pubspec.lock with that version number.

Recall that your pubspec.yaml has the following generalgénéral version:

While pubspec.lock has the specific version:

Now run the upgrade:

If you look at pubspec.yaml it still stays ^0.3.0 but now pubspec.lock specifies 0.3.2, a version upgrade!

Upgrading beta packages

Because of semantic versioning, a package number that starts with 0.x.x will only upgrade the last of the three version numbers (known as the patch version). That’s why the upgrade command only moved 0.3.1 to 0.3.2 and not 0.4.0, which also exists. For pre-1.0.0 releases, a changeune changer in the secondla seconde number (the minor version) is potentially a breaking change. And you wouldn’t want a breaking change to happen automatically!

Upgrading stable packages

If the current version of some package were ^1.0.0 in pubspec.yaml and 1.2.0 in pubspec.lock, but version 1.3.0 existed on pub.dev, then running flutter pub upgrade would increment the minor version number: that is, pubspec.lock would now have 1.3.0.

However, if version 2.0.0 were also available on pub.dev (where 2 is the major version), upgrade would not make that change. That’s because a change in the majorles majeure version numbernombre for stablestables packages is likely a breaking change. The Pub tool wants to let developers make the decision themselves for when to perform a breaking upgrade.

Upgrading major versions

Eventually you do want to upgrade to package versions that may contain breaking changes. You can tell Pub to do that by adding the --major-versions flag. Try that now:

This not only updates your pubspec.lock file but also pubspec.yaml. You’ll get the following notification of that change:

Confirm that’s true by checking your pubspec.yaml file:

When you have a whole bunch of packages in your project, using the --major-versions flag is a lot easier than checking pub.dev for every package to see if one of them has an update!

Honorable mention

  • flutter pub upgrade --dry-run: This allows you to see what new package versionsversio are availabledisponible without actually upgrading. However, you might as well use outdated if this is what you want. See the next section.

outdated

This command gives you information about what you can update. To see it in action, change your audio videovidéo progress bar version back to ^0.3.0 in pubspec.yaml and 0.3.1 in pubspec.lock, and run flutter pub get again.

Then run the following command:

This is what you get:

Current shows the version in pubspec.lock, Upgradable shows what running flutter pub upgrade would give you, and Resolvable shows you what running flutter pub upgrade --major-versions would give you. The * indicates that a version is not the latest available version.

Note: The meta package above is not resolvable to the latest version because it’s a transitive dependency. That is, it’s a dependency of a dependency (probably in the Flutter framework), so you’ll have to wait for that dependency to update it before you’ll have the latest version of meta. My guess is that there weren’t any life changing updates in meta 1.4.0 so you’re probably OK.

downgrade

You’re not likely to use this one very often, but it does the opposite of upgrade. As long as you still have your pubspec.yaml set to ^0.3.0 for audio_video_progress_bar and pubspec.lock set to 0.3.1, then try running the following:

This updates the version in pubspec.lock to 0.3.0, but no lower, even though lower versions exist on pub.dev. Downgrading to 0.1.0 would be a breaking change, so Pub doesn’t do that.

OK, we’re done playing around with versions now, so you can upgrade back up to the latest version:

deps

This gives you a visual representation of all of the dependencies in your project. Try it out:

Here’s the output:

Well, that answers the question about whose dependency meta is, anyway.

Honorable mention:

  • flutter pub deps --no-dev: This excludes the dev dependencies, so that leaves out all of those flutter_test dependencies in the printout above.

cache

Whenever you run flutter pub get or flutter pub upgrade, Pub caches the dependencies of your project in a central location, called the system cache. That way all of your projects can share the same packages, which saves on disk space. As you saw earlier, you can find the location of your system cache by checking the contents of .dart_tools/package_config.json. For me it’s in the .pub-cache folder of my home folder.

Sometimes you might want to cache a package from pub.dev without actually going to the trouble of adding that package to a pubspec.yaml file and running flutter pub get.

Let’s try that. Run the following command to add the mongol package to the system cache:

This downloads the most recent version, which at the time of this writing is 2.0.0, but if you want to download every version that I’ve ever published then you can add the --all flag:

You can see that by checking your system cache folder:

Yep, they’re aaaaall there. Now you’re all set to add vertical Mongolian script to your app when you go out to visit your friends in middle of the Gobi and don’t have access to the internet.

mongol package demo

Repairing the cache

If you’re afraid that your system cache was corrupted, you can easily repair it. Try deleting a random file inside one of the cached packages in your system cache (but not the entire folder).

Now run the following command:

This will re-download all of the packages in your system cache. You’ll see that the file you deleted is back again.

Clearing the cache

There is no Pub command that I know of to clear the cache, but you can easily delete all of the packages there manually. Version 0.0.1 of the mongol package wasn’t really that good anyway, so you don’t need it taking up your disk space anymore.

Pub will download all the packages it needs the next time you run flutter pub get. That is, as long as you’re not in middlemilieu of the Gobi without Wi-Fi.

Upgrading and downgrading without an internet connection

If you don’t have access to the internet but you have already cached different versions of a package, then you can upgrade or downgrade using the --offline flag.

This will just look what’s available in your systemsystème cache rather than checking pub.dev.

add

If you’re too lazy to open pubspec.yaml and write the name of package that you want to use, then the add command is for you!

Check your pubspec.yaml file and the mongol librarybibliothèque should be in your listliste of dependencies now:

I’m just kidding about the lazy comment. This is how pub.dev shows you how to install packages to a project now (example).

The add command is also probably meant to make it easier for IDE plugins to add packages for you. Or you might be one of those command-line geniuses who never touch a mouse.

As with almost all of the Pub commands, you can see the other available sub-options by adding the -h flag:

There are quite a few other sub-options available here, but I’ll leave them for the IDE plugin developers and command-line geniuses to explore.

remove

This is just the reverse of add. In order to remove the mongol package from your pubspec.yaml file, run the following command

Personally, I probably won’t be using remove much. I’ll just take an extra five seconds to open pubspec.yaml and delete that line myself. But then, I’m not an IDE plugin developer or command-line genius.

global

This command is useful for running Dart applications from anywhere on your machine.

Activating a pub.dev package

The following command installs the flutter_gen package in the global_packages and bin folders of your Pub system cache:

This allows you to run the fluttergen command from anywhere (as long as you have the path set up).

Activating a local package

You can also use the global command to run your own Dart scripts. Normally when you create a Dart app, you can only run it by specifying the path:

However, if you install the app using global and specify the --source path to the project’s root folder like so:

Then you can run the app from anywhere on your computer like this:

Note: Supposedly you should be able to just run the app using hello_app directly, but I haven’t been able to figure out how to do that. Help me out if you know how. Update: This appears to be a bug because of a reference to pub instead of dart pub. I expect that another update soon will fix it. Track the issue here. Ping me to update this article when it’s solved. Find my workaround here.

Listing installed packages

You can see all of your activated global packages like so:

which will show something like this:

The first two are from pub.dev and the last one is my own.

Uninstalling global packages

If you want to uninstall a global package then use the deactivate keyword:

Publishing packages

Pub has a number of commands related to publishing packages on pub.dev.

login and logout

In order to publish a package to pub.dev you need to be logged in. You can log in or log out as follows:

Logging in will store your login credentials in a file called credentials.json in the root of the Pub system cache.

But I never directly use login and logout. I think the publish command already incorporates login if you aren’t logged in already.

publish

Every time I finish an update for one of my packages on pub.dev, I do a dry run in my package root to see if everything is OK:

This doesn’t actually publish the updates. It just tells me if there are any problems. If there aren’t any, then I publish it for real like so:

A few seconds lateraprès my package update is available on pub.dev and you all can use it by running flutter pub upgrade.

If you’d like to learn more about making your own packages, read Developing packages & plugins in the Flutter documentation.

uploader

If more than one person are working on a package, you can add additional uploaders like so from the root of your project:

You may have seen this on pub.dev already:

Uploaders for the jaguar web server package

However, the docs recommend using a verified publisher instead now, so it’s a little unclear to me how multiple uploaders work in that scenario. I haven’t needed that feature yet myself. Feel free to comment below if you have experienceexpérience with this.

Odds and ends

There are just a few other commands that we haven’t covered, but they don’t seem too important. I’ll just briefly mention them.

pub pub

Here is an exampleun exemple of the double pub:

The first pub is the Flutter version of Pub and the second pub gives you the Dart version of Pub. It’s unclear to me why this is necessary. You can just use dart pub get, right?

pub test

You would run this in the rootla racine of a project.

This looks for the test package and runs the tests in the test folder. However, it’s unclear to me why this is necessary. Just use flutter test or dart test, right?

pub run

Here is a generic example:

If you just want to run your Flutter or Dart app, you can just use flutter run or dart run. I’m not really sure what pub run is there for unless it’s to run an executable inside your project beyond the app itself.

Conclusion

That covers almost every corner of the Pub command line tool. There were a few other stray sub-commands, but you can read about them in the documentation.

Again, if you know the answers to any of the points I wasn’t clear about, or if I left out something important, please leave a comment below.

Follow Flutter Community on Twitter 🐥: https://www.twitter.com/FlutterComm

Flutter Community

Articles and Stories from the Flutter Community

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store