pubup 0.7.0
pubup: ^0.7.0 copied to clipboard
Automatically update pubspec.yaml dependency constraints to the latest resolvable versions across Dart and Flutter workspace packages.
pubup #
A Dart CLI tool that automatically updates pubspec.yaml dependency constraints
to the latest resolvable versions — across single packages and Dart/Flutter
workspaces.
Unlike dart pub upgrade, which only updates pubspec.lock within existing
constraints, pubup rewrites the version constraints in your
pubspec.yaml files so they reflect what is actually resolvable today.
Installation #
dart pub global activate pubup
Make sure ~/.pub-cache/bin is on your PATH.
Updating #
# Manual upgrade
dart pub global activate pubup
# Or use the built-in command
pubup update
pubup checks pub.dev for new releases at most once per day and prints a notice on stderr when a newer version is available. The check is skipped automatically when:
CI=truePUBUP_DISABLE_UPDATE_CHECK=1- stderr is not a TTY (e.g. invoked by a coding agent, captured by a script, or piped)
For coding agents #
If you're an LLM-driven coding agent (or you ship one), see
AGENTS.md for the recommended workflow, when to prefer pubup
over dart pub upgrade, and how to interpret exit codes.
Usage #
Run from the root of any Dart or Flutter project:
# Preview what would change (no files modified)
pubup --dry-run
# Apply updates to all workspace packages
pubup
# Update only a specific package in a workspace
pubup --package my_package
# Skip dev_dependencies
pubup --no-dev
# Avoid major-version bumps (only update within the current major)
pubup --bump minor
# Only take patch updates
pubup --bump patch
# Allow stable dependencies to move to pre-releases (e.g. 2.0.0-rc.1)
pubup --prereleases
# Run pub with a specific Flutter or Dart SDK
pubup --sdk /path/to/flutter
# Specify a custom project root
pubup --root /path/to/project
Limiting how far constraints move #
By default pubup bumps each constraint to the latest resolvable version,
including across major versions. Pass --bump to keep updates inside a
narrower window so you can refresh dependencies without taking breaking
changes:
| Flag | What gets bumped |
|---|---|
--bump major (default) |
Latest resolvable, including new major versions. |
--bump minor |
Highest version that keeps the leading segment unchanged (e.g. 1.2.3 → up to 1.x.y, 0.1.2 → up to 0.x.y). |
--bump patch |
Highest version that keeps the leading two segments unchanged (e.g. 1.2.3 → up to 1.2.x). |
When the latest resolvable version exceeds the bound, pubup queries pub.dev's package API for the full version list and picks the highest non-prerelease version that fits — so you still get the newest patch (or minor+patch) instead of skipping the dependency entirely.
If no in-bound version above the currently locked one exists, the dependency
is reported under Skipped as above --bump in the summary.
Pre-releases #
pub outdated can report a pre-release as the resolvable version even when
the dependency is on a stable release (e.g. sentry_flutter 9.30.0 with
10.0.0-rc.2 resolvable while 9.30.1 is the latest stable). pubup never
moves a stable dependency to a pre-release by default. It picks the newest
stable version between the locked and the resolvable version instead.
If only a pre-release is newer, the dependency is reported under Skipped as
prerelease-only. Pass --prereleases to accept pre-releases. Dependencies
already on a pre-release (e.g. 6.2.0-beta.3) keep moving along pre-releases
without the flag.
Which SDK pubup uses #
pubup runs flutter pub or dart pub from the first SDK it finds:
--sdk <path>, a Flutter or Dart SDK directory.- The FVM pin in the project's
.fvmrc, linked at.fvm/versions/<version>. If the pinned version is not linked, pubup warns and falls back toPATH. - The legacy FVM link
.fvm/flutter_sdk. flutteranddartonPATH.
The SDK decides which versions are resolvable, so the header shows which one was used:
Workspace: my-app (flutter pub)
SDK: Flutter 3.38.5, Dart 3.10.4 (FVM .fvm/versions/3.38.5)
How it works #
- Discovers workspace packages from the root
pubspec.yamlworkspace:section. Falls back to the root package only if no workspace is defined. - Picks the SDK (see Which SDK pubup uses).
- Runs
dart pub outdated --json --show-all(orflutter pubfor Flutter packages) for each package. - Compares declared constraints in
pubspec.yamlagainst the latest resolvable version reported by pub. - Updates constraints using one of two strategies:
- Workspace projects (root declares
workspace:): shared dependencies are updated coordinated across every member that declares them. pubup rewrites all affectedpubspec.yamlfiles, then runs one root-levelpub getfor the whole batch. On solver failure, it retries per dependency to attribute the exact failure. - Single-package projects: a single batched
dart pub addper package (all out-of-date deps in one call). If the batched call fails, pubup falls back to per-dependencydart pub addcalls so individual failures are reported accurately.
- Workspace projects (root declares
With --package, workspace mode only considers outdated deps reported for the
filtered members. A coordinated bump is skipped (with a warning) when
another workspace member also declares that dependency but is outside the
filter — run without --package for a workspace-wide update.
What gets skipped #
The tool intentionally skips dependencies that:
- Use
path:,git:, orsdk:sources - Have
anyor non-standard version constraints - Are already at
^<resolvable>(up to date) - Are stable and only have a newer pre-release (unless
--prereleases) - Are transitive (not declared directly in your pubspec)
- Entries under
dependency_overrides:(never modified)
Held-back dependencies #
When pub.dev has a newer version than pub can resolve, another dependency or
the SDK is blocking it. pubup cannot move these, so it lists them in a
Held back section above the summary:
Held back (2)
-------------
Another dependency or the SDK blocks the latest version of these.
equatable direct resolvable 2.1.0 latest 3.0.0
freezed dev resolvable 4.0.1 latest 4.0.2
Held-back dependencies do not affect the exit code.
CLI flags #
| Flag | Description | Default |
|---|---|---|
--dry-run |
Preview changes without modifying files | false |
--[no-]dev |
Include dev_dependencies |
true |
--package <name> |
Filter to specific workspace package(s); repeatable | all |
--root <path> |
Project root directory | . |
--bump <level> |
Cap how far constraints move: major, minor, or patch |
major |
--prereleases |
Allow stable dependencies to move to pre-releases | false |
--sdk <path> |
Flutter or Dart SDK to run pub with | FVM pin, then PATH |
--version, -V |
Print the current version | — |
Subcommands #
| Command | Description |
|---|---|
update |
Reinstall pubup from pub.dev (dart pub global activate pubup) |
Exit codes #
| Code | Meaning |
|---|---|
0 |
All updates succeeded (or nothing to update) |
1 |
One or more updates failed |
Example output #
Single package:
SDK: Flutter 3.38.5, Dart 3.10.4 (PATH: /Users/me/flutter)
Package: . (flutter pub)
go_router direct ^17.0.0 -> ^17.1.0
firebase_core direct ^4.2.1 -> ^4.6.0
very_good_analysis dev ^10.0.0 -> ^10.2.0
Summary
-------
Updated 3
Failed 0
Workspace (rows show shared from constraints across members and how many
members each coordinated update touches):
Workspace: my-app (flutter pub)
SDK: Flutter 3.38.5, Dart 3.10.4 (FVM .fvm/versions/3.38.5)
build_runner dev ^2.4.13, ^2.4.15 -> ^2.15.0 8 members
freezed dev ^3.0.3, ^3.0.6 -> ^3.2.5 6 members
very_good_analysis dev ^6.0.0 -> ^10.2.0 39 members
bloc direct ^9.0.0 -> ^9.2.1 4 members
go_router direct ^15.1.2 -> ^17.2.3 2 members
Summary
-------
Updated 175 constraints across 56 dependencies
Failed 0
Skipped 54 up-to-date, 84 non-hosted, 3041 transitive
When updates fail, the resolver error is wrapped under a Failures section
above the summary so the totals stay visible at the bottom of the output.
Held back dependencies are listed above Failures.
Contributing #
Contributions are welcome! Please file issues and pull requests on GitHub.
CI checks formatting, runs dart analyze --fatal-infos, and requires the tests
to cover every line in lib/. Run tool/coverage.sh to check coverage locally;
it lists any line that is not covered.
License #
MIT — see LICENSE for details.