React hook for detecting and handling PWA (Progressive Web App) installation.
Other PWA install hooks miss the beforeinstallprompt event when it fires before React hydration. use-pwa captures the event at module load time, so the install button shows up reliably even on the first paint.
Note on iOS:
isSupportedisfalsebecause iOS does not exposeBeforeInstallPromptEvent. "Add to Home Screen" there is a manual user gesture, not programmatic. UseneedsManualInstallto show your own instructions instead of an install button. Since iOS 16.4 this covers Chrome, Edge, Firefox and DuckDuckGo too, not just Safari — but not in-app browsers such as Instagram or LINE, which report the same platform yet cannot add to the home screen.
Importing use-pwa — not calling the hook, just importing it — adds a beforeinstallprompt listener to window that stays for the life of the page. That is what lets it catch an event fired before React hydrates.
The listener calls event.preventDefault(), which stops the browser from showing its own install mini-infobar (Chrome on Android). From then on the install prompt appears only when your code calls install(). If you want the browser's default UI, do not import this package on that page.
The package declares "sideEffects": true so bundlers keep the listener even when the module is imported only for this effect.
npm install use-pwaimport usePwa from "use-pwa";
function App() {
const { canInstall, install, isInstalled, needsManualInstall } = usePwa();
if (isInstalled) {
return null;
}
if (needsManualInstall) {
return <p>Tap the share button, then Add to Home Screen.</p>;
}
return (
<button disabled={!canInstall} onClick={install}>
Install PWA
</button>
);
}| Property | Type | Description |
|---|---|---|
canInstall |
boolean |
true when install prompt is available |
install |
() => Promise<UserChoice | undefined> |
Triggers the install prompt. Never rejects; resolves with undefined when no prompt is available |
isInstalled |
boolean |
true when running as installed PWA. Updates live, without a reload |
isSupported |
boolean |
true when browser supports PWA installation |
needsManualInstall |
boolean |
true when the platform can only install by hand — iOS and iPadOS. Mutually exclusive with canInstall |
Returned by install() when the user responds to the prompt:
| Property | Type | Description |
|---|---|---|
outcome |
"accepted" | "dismissed" |
User's choice |
platform |
string |
Platform string |
- Simple 5-property API
- Detects PWA install prompts
- Browser support detection, with an iOS manual-install signal
- Standalone mode detection, kept up to date after install
- SSR compatible
- TypeScript support
MIT