react-native-versionpilot
v0.1.2
Published
React Native app update checker for Android and iOS — Play Store / App Store version check, force update, dialogs, and store redirect.
Maintainers
Readme
react-native-versionpilot
I kept rewriting the same "check for update" screen in every app — hit the Play Store / App Store, compare versions, show a modal, block the back button if it's a critical release. This is that logic packaged as one component so I (and hopefully you) never have to write it again.
Preview
Install
yarn add react-native-versionpilot
cd ios && pod installIt's a native module, so a full rebuild is needed after install — a Metro reload won't pick it up.
Get it running
Wrap your app once:
import { VersionPilot } from 'react-native-versionpilot';
export default function App() {
return (
<VersionPilot>
<Navigation />
</VersionPilot>
);
}On launch it grabs the current version, hits the store for the latest one, and shows a dialog if there's something newer. No other setup.
If you want it pointed at specific store listings instead of guessing from the bundle id:
<VersionPilot
country="IN"
iosAppId="6443614190"
androidPackageName="com.languageacademy"
theme={{ primaryColor: '#1b4e73' }}
>
<Navigation />
</VersionPilot>Update modes
Most apps need three different behaviors depending on how big the release is, so all three are built in.
Optional — the default. Shows Update / Later.
<VersionPilot force={false} />Force — only an Update button, and on Android the hardware back button is disabled so people can't dismiss it.
<VersionPilot force />Auto force on major/minor — instead of deciding manually, let the version bump decide:
<VersionPilot autoForceOnMinor />| Bump | e.g. | Behavior | | --- | --- | --- | | major | 1.0.0 → 2.0.0 | forced | | minor | 1.0.0 → 1.2.0 | forced | | patch | 1.0.0 → 1.0.5 | optional |
And if you'd rather not show anything automatically and just want the data:
import AppUpdate from 'react-native-versionpilot';
const result = await AppUpdate.check({ showDialog: false });
if (result.updateAvailable) {
AppUpdate.showDialog(result);
}What you get back
const result = await AppUpdate.check();
// {
// updateAvailable: true,
// currentVersion: '1.0.0',
// latestVersion: '1.2.0',
// forceUpdate: false,
// storeUrl: 'https://...',
// releaseNotes: '...',
// }<VersionPilot> props
| Prop | Type | Default |
| --- | --- | --- |
| autoCheck | boolean | true |
| checkOnForeground | boolean | true |
| force | boolean | false |
| autoForceOnMinor | boolean | false |
| country | string | "US" |
| iosAppId | string | — |
| androidPackageName | string | — |
| theme | DialogTheme | teal-ish defaults |
| title / message | string | — |
| updateButtonText / cancelButtonText | string | "Update" / "Later" |
Making it look like your app
The default theme is a plain teal card, which is intentionally boring so you'll want to change it:
<VersionPilot
theme={{
primaryColor: '#1b4e73',
backgroundColor: '#FFFFFF',
borderRadius: 24,
}}
title="New Update"
message="A new version is available."
/>If theming isn't enough and you want to throw the whole layout away:
<VersionPilot
renderContent={({ title, message, onUpdate, onLater, forceUpdate }) => (
<>{/* whatever you want here */}</>
)}
/>The dialog itself is also responsive — text and spacing scale with screen width instead of being fixed pixel values, so it doesn't look oversized on a small phone or cramped on a tablet.
The rest of the API
Things you probably won't need on day one, but are there if you do.
<VersionPilot
styles={{
card: { paddingTop: 32 },
title: { fontSize: 24 },
updateButton: { minHeight: 52 },
}}
icon={require('./assets/update.png')}
buttonLayout="horizontal"
/>import { UpdateDialog, useAppUpdate } from 'react-native-versionpilot';
const { result, visible, openStore, hideDialog } = useAppUpdate({ showDialog: false });
<UpdateDialog visible={visible} result={result} onUpdate={openStore} onLater={hideDialog} />AppUpdate.addListener('updateFound', result => {});
AppUpdate.addListener('updated', result => {});
AppUpdate.addListener('later', result => {});
AppUpdate.removeAllListeners();AppUpdate.showDialog(result);
AppUpdate.hideDialog();
AppUpdate.openStore();
AppUpdate.getCurrentVersion();
AppUpdate.getBuildNumber();
AppUpdate.configure({ country: 'IN', autoForceOnMinor: true });How it actually finds the version
- iOS — the iTunes lookup API, by bundle id or App Store numeric id.
- Android — there's no public Play Store API, so it reads the version straight off the store listing page. This is the same trick most update-check libraries use; if Google changes their HTML this could need a fix, so open an issue if it stops working.
Expo
The store-checking part is plain fetch, so it works fine in Expo Go. The native bits (reading the installed version/build number) need a dev client or a bare build — or just pass them in yourself:
await AppUpdate.check({
currentVersion: '1.0.0',
androidPackageName: 'com.example.app',
iosAppId: '1234567890',
});License
MIT — Pawan Vishwakarma
