pub: the Dart package manager, and how to work on it
The pub command line tool
At a glance
- What is it?
- dart-lang/pub is the source of the pub command, the tool that resolves and fetches Dart dependencies. This repository is not a package you consume but the tool itself, written in Dart, and its own README is mostly a guide for contributors, from running the tool out of the checkout to splitting tests into unit and integration forms.
- Who is it for?
- Adopt pub as your dependency resolver if you write Dart, since it is the tool that turns a pubspec.yaml into a resolved dependency graph for both `dart pub get` and `flutter pub get`. Do not treat this repository as a library you import, because the README states pub is not a package and that all of the implementation sits under lib/src/ with nothing intended for public consumption, so its API is not a contract.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A tool that is organised like a package but is not one
Pub is the package manager for Dart, and the repository that hosts it is an unusual thing to find on GitHub. The README says it outright: pub isn't a package, but it's organized like one. The implementation is all under lib/src/, since there are no libraries intended for public consumption, which means there is no importable API to depend on and no stability promise attached to one. The tree at the root is the standard Dart package layout anyway: lib/, test/, bin/, plus tool/, doc/, pubspec.yaml, pubspec.lock, analysis_options.yaml and a dart_test.yaml. The presence of pubspec.yaml and pubspec.lock in the repository is a small joke that is also practical: the tool that resolves dependencies is itself resolved by the same mechanism, so a broken pub cannot build pub. The licensing is BSD-3-Clause, which is the usual choice for a tool inside the Dart ecosystem, and the AUTHORS file and CONTRIBUTING.md sit alongside the source.
One entrypoint, one command per file
The mechanism is deliberately conventional. The bin/ directory contains pub.dart, the entrypoint script that runs whenever a user types pub on the command line or runs it in the Dart editor, and it is usually invoked through shell scripts in sdk/bin at the root of the Dart repository. The instruction for contributors is that it is probably easiest to start by looking at a particular pub command, and each command is encapsulated in its own files under lib/src/command/. That is the whole architecture in two sentences: an entrypoint that dispatches, and a directory of command implementations that do not know about each other. It is a design that has survived a long time, and the reason is that the extension mechanism of a package manager is exactly a set of commands, so the internal structure of the tool mirrors its public surface. The one structural note to keep in mind is that a new user-visible command is a new file in that directory, and the rest of the tool can stay out of it.
Running pub straight from the checkout
To work on pub you run it from the git repository rather than installing it, and the command is a single line:
dart bin/pub.dartThat is the whole local workflow for seeing your changes take effect, with no build step and no packaging. The scripts in sdk/bin of the Dart repository are how the shipped version is started, which tells you the checkout version and the released version differ in entrypoint rather than in behaviour. The tooling side is equally small. The tool/ directory holds the test runner, and the tests are invoked as:
dart tool/test.dart test/path/to_test.dartfor a single file, and:
dart tool/test.dartfor everything at once. The project states that before any change is made to pub, all tests should pass, which is a stricter rule than most repositories state and implies the suite is expected to be green on a fresh checkout, not just after your patch. The build status badge in the README points at a Dart CI workflow on the main branch, so the same suite runs in continuous integration.
Two test styles, split by how long they take
The testing guidance is the part of this README that is most transferable, because it describes a pattern any large command-line tool ends up needing. Pub tests come in two basic forms. The first, usually used to unit test classes and libraries internal to pub, has many tests in a single file, and it is used when each test takes a short time. The example given is test/version_test.dart, which contains unit tests for pub's Version class. The second form, used by most of the suite, is for integration tests of user-visible pub commands, and each test has a file to itself, named after the test description. The stated reason is timing: a file per test avoids timeouts when the tests run on the build bots. The worked example is tests/get/hosted/get_transitive_test.dart, which tests the resolution of transitive hosted dependencies when using `dart pub get` or `flutter pub get`. The rule for a new test is to find a similar test in test/ and follow the same patterns, and any change to pub should be accompanied by one or more tests that exercise the new functionality.
Contributing starts with a message, not a pull request
The contribution process here is the first thing that would surprise a developer used to opening a pull request straight away. The README asks that the first step towards contributing is to contact the pub dev team and let them know what you are working on, so that the team can be sure not to start working on the same thing at the same time, and to open an issue stating what you plan to work on. It says this will also let the team give specific advice about where to start. The reasoning is straightforward for a tool that the Dart SDK depends on: pub sits in the critical path of every Dart build, so a duplicated effort or a badly scoped change is expensive in a way it is not for an isolated library. The project also states that contributing to a new project can be hard because there is a lot of new code and practices to learn, and points readers to the pub tool documentation for more background. On landing a patch, all patches to official Dart packages, including pub, need to undergo code review before submission, with the full process documented in the Dart SDK's own CONTRIBUTING file.
Where the documentation is thin
This repository is not where you learn to use pub. The README is explicit that it is aimed at contributors, and it links out for user-facing material: the pub tool documentation at dart.dev/tools/pub/cmd, which the homepage of the project also points to. The doc/ directory in the tree presumably holds the reference, and the issue tracker is used for both feature requests and bug reports but the repository does not reproduce the command reference, the pubspec format documentation or the resolution algorithm description. That means an engineer evaluating pub has to read the user documentation first and treat this repository as the implementation. The last push was on 2026-10-12, so the code is current, but the release tags in the repository are SDK-2.0.0-dev builds dated 2018, which reflects how the tool is versioned as part of the SDK rather than as an independent package with its own release cadence.
How this differs from building your own resolver
The alternative for a team that wants control over dependency handling is to write a resolver and fetcher themselves, or to generate a lockfile with a bespoke tool. The difference in approach is the whole point of a package manager. Pub owns the resolution problem: given a pubspec.yaml with a set of constraints, it picks a set of versions that satisfies every constraint simultaneously, across direct and transitive dependencies, and it records that choice in pubspec.lock so a later build is reproducible. The version constraint language, the hosted repository protocol, the caching, the content hashing and the handling of a package that turns out to be yanked are all problems that look small until you hit them. Writing your own means reimplementing a satisfiability problem and then keeping it correct as the ecosystem moves. The cost of using pub instead is that you inherit its rules, including the constraint syntax and the resolution behaviour, and that your build now depends on a hosted repository being reachable when a lockfile entry is missing.
Editorial conclusion
Adopt pub as your dependency resolver if you write Dart, since it is the tool that turns a pubspec.yaml into a resolved dependency graph for both `dart pub get` and `flutter pub get`. Do not treat this repository as a library you import, because the README states pub is not a package and that all of the implementation sits under lib/src/ with nothing intended for public consumption, so its API is not a contract. Before you open a patch, contact the pub dev team with an issue describing your plan, since the project asks contributors to do that first, and run the test suite with `dart tool/test.dart` before you submit anything.
Frequently asked questions
Can I import pub as a Dart library?
No. The README states that pub isn't a package but is organized like one, and that the implementation is all in lib/src/ since there are no libraries intended for public consumption.
How do I run pub from a git checkout?
Run `dart bin/pub.dart` from the repository root. The bin directory holds pub.dart, the entrypoint script that runs when a user types pub on the command line or in the Dart editor.
How are pub's tests run?
With `dart tool/test.dart` for the whole suite, or `dart tool/test.dart test/path/to_test.dart` for a single file. The project asks that all tests pass before any change is made, and the suite runs in a Dart CI workflow on the main branch.
What are the two styles of pub test?
Unit tests for internal classes put many tests in one file and run quickly, for example test/version_test.dart for the Version class. Integration tests for user-visible commands give each test its own file named after the description, so long-running tests do not time out on the build bots.
What licence is pub released under?
The repository is licensed under BSD-3-Clause, with the LICENSE file at the root of the tree. The last push to the repository was on 2026-10-12.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/dart-lang-pub)Was this useful?