upgrader is a Flutter package that automatically detects when a newer version of your app is available on Google Play or the App Store, then shows a native-style dialog prompting users to update — with zero backend setup required.
The library — authored by Larry Aasen — compares the installed app version against the latest version in the Google Play Store or Apple App Store and presents an UpgradeAlert dialog or UpgradeCard widget when the store version is newer. No server, no version file, no configuration for mobile platforms.
On Android and iOS, the library queries the store API directly, parses the version string, and compares it to the installed build reported by package_info_plus. No setup beyond adding the dependency.
On macOS (direct distribution), Windows, Linux, and Web, the library reads an Appcast RSS 2.0 feed you host. The same format powers the Sparkle framework on macOS — one XML file controls the version prompt across all non-store platforms.
Set minAppVersion to a semver string. When the installed version falls below that floor, the IGNORE and LATER buttons disappear and the dialog becomes non-dismissible — users must update before continuing.
Every dialog string ships pre-translated. Arabic, Hebrew, Farsi, and Urdu render right-to-left without any extra configuration. Override any string via UpgraderMessages to match your app's tone.
Each time the app starts (and again on resume, when checkOnResume is true), the library runs three steps before deciding whether to show the update prompt.
On Android it scrapes the Google Play page; on iOS it calls the iTunes Search API. On desktop and web it downloads the Appcast XML feed from the URL you configured.
The library parses both versions as semantic version strings and compares them. If the store version is strictly greater, the update flow continues. If they are equal or the store version is lower, nothing happens.
The library checks whether the user already tapped IGNORE for this version, or whether the durationUntilAlertAgain window has passed since they tapped LATER. Only if both gates clear does the dialog render.
| Platform | Version source | Detection | Extra setup |
|---|---|---|---|
| Android | Google Play Store | ✓ Auto | None |
| iOS | Apple App Store | ✓ Auto | None |
| macOS | Mac App Store | ✓ Auto | None (App Store build) |
| macOS | Direct / notarized | ⚙ Appcast | Host appcast.xml |
| Windows | Custom feed | ⚙ Appcast | Host appcast.xml |
| Linux | Custom feed | ⚙ Appcast | Host appcast.xml |
| Web | Custom feed | ⚙ Appcast | Host appcast.xml |
The fastest path to a working update prompt on Android and iOS takes under five minutes and requires no backend changes. The three steps below cover the entire integration: add the dependency, import the library, and wrap your home screen widget. Everything after that — store lookup, version parsing, dialog display, and re-prompt timing — is handled automatically.
Step 1 — Add the dependency
$ flutter pub add upgrader # or manually in pubspec.yaml: dependencies: upgrader: ^13.7.0
Step 2 — Import the library
import 'package:upgrader/upgrader.dart';
Step 3 — Wrap your home widget
return MaterialApp( home: UpgradeAlert( child: MyHomePage(), ), ); // UpgradeAlert must be below MaterialApp in the widget tree
That is all for Android and iOS. The library handles store lookup, version comparison, and re-prompt timing automatically.
Choose the widget that fits your UX — or use both simultaneously with a shared Upgrader instance.
Pass these to the Upgrader() constructor. The instance can be shared between UpgradeAlert and UpgradeCard via the named upgrader: parameter, so both widgets stay in sync.
| Parameter | Type | Default | Description |
|---|---|---|---|
| durationUntilAlertAgain | Duration | 3 days | Silence period after the user taps LATER before the dialog appears again. |
| minAppVersion | String? | null | Semver minimum. Below this version the upgrade is forced — IGNORE and LATER are hidden. |
| dialogStyle | UpgradeDialogStyle | material | Switch to cupertino for an iOS ActionSheet-style prompt on all platforms. |
| checkOnResume | bool | true | Re-runs the store version check each time the app returns from background. |
| barrierDismissible | bool | false | Whether tapping outside the dialog dismisses it without action. |
| debugLogging | bool | false | Prints store endpoint, raw version string, and comparison result to the debug console. |
| debugDisplayAlways | bool | false | Forces the dialog on every rebuild — use in debug mode only to inspect UI. |
| messages | UpgraderMessages? | null | Override title, body, button labels, or release-notes text for any language. |
| storeController | UpgraderStoreController? | null | Plug in UpgraderAppcastStore to enable desktop and web update detection. |
| shouldPopScope | BoolCallback? | null | Controls whether the system back gesture can close the upgrade dialog. |
All dialog strings are compiled into the package. RTL scripts (Arabic, Hebrew, Farsi, Urdu) render correctly without additional configuration. To add a new locale or customize any phrase, subclass UpgraderMessages and pass the instance to the constructor.
No additional Flutter localization setup is required — no arb files, no intl dependency, no locale delegate configuration. Each string (title, body, IGNORE, LATER, UPDATE NOW, and the release notes label) can be overridden individually, so you can match your app's tone in any of the 39 supported languages without forking the repository or patching source files.
minAppVersion: '2.0.0' (or whichever version you require) to the Upgrader constructor. When the device's installed version is below that floor, the library hides the IGNORE and LATER buttons and sets barrierDismissible to false. The only available action is UPDATE NOW, which opens the store page. This is the right approach after a breaking API change or a critical security fix where older builds should not run at all.
debugDisplayAlways: true and debugLogging: true to the Upgrader constructor. The first parameter makes the dialog render on every hot reload regardless of the version comparison result. The second prints the full lookup trace — endpoint called, raw version string returned, parsed version, and comparison outcome — to the debug console. Remove both before building a production release.
Free, open source, MIT licensed. Add one dependency and let the library handle the rest.