A general-purpose PWA utilities package for detecting installation, platform detection, and generating PWA configurations
npm install @polterware/pwa


A general-purpose PWA utilities package for detecting installation, platform detection, and PWA install instructions. Works with any framework or vanilla JavaScript.
- Installation Detection: Detect if your PWA is already installed
- Platform Detection: Detect iOS, Android, macOS Safari, Desktop, and other platforms
- Install Instructions: Get platform-specific install instructions
- Interactive CLI: Interactive setup tool to create or update PWA manifest
- React Hooks: React hooks for easy integration
- UI Agnostic: No UI dependencies - use with any UI library
- TypeScript: Full TypeScript support with type definitions
``bash`
npm install @polterware/pwa
For React support (peer dependency):
`bash`
npm install react react-dom
---
`typescript
// Core functions (vanilla JS/TS)
import {
detectInstalled, // Check if PWA is installed
detectPlatform, // Get current platform
getInstallInstructions, // Get platform-specific instructions
} from "@polterware/pwa";
// React hooks & components
import {
usePWA, // Combined hook (recommended) - returns { isInstalled, platform }
useIsInstalled, // Simple boolean hook - returns isInstalled status
usePlatform, // Returns detected platform
InstallPrompt, // UI-agnostic install prompt component
} from "@polterware/pwa/react";
// Types
import type {
Platform, // 'ios' | 'android' | 'macos_safari' | 'desktop' | 'other'
Locale, // 'en' | 'pt-BR' | 'es'
InstallInstructions, // Install instructions object
InstallInstruction, // Single instruction step
} from "@polterware/pwa";
`
| Hook | Returns | Use Case |
| ------------------ | --------------------------- | ------------------------------------------------------- |
| usePWA() | { isInstalled, platform } | Recommended - need both install status AND platform |useIsInstalled()
| | boolean | Simple check if app is installed as PWA |usePlatform()
| | Platform | Only need platform detection |
---
`typescript
import {
detectInstalled,
detectPlatform,
getInstallInstructions,
} from "@polterware/pwa";
const isInstalled = detectInstalled();
const platform = detectPlatform(); // 'ios' | 'android' | 'macos_safari' | 'desktop' | 'other'
const instructions = getInstallInstructions(platform);
console.log(instructions.title); // Platform-specific title
console.log(instructions.steps); // Array of installation steps
`
`tsx
import { usePWA, InstallPrompt } from "@polterware/pwa/react";
function MyApp() {
const { isInstalled, platform } = usePWA();
if (isInstalled) {
return
return (
renderTrigger={(instructions) => (
)}
renderInstructions={(instructions) => (
{instructions.subtitle}
{step.description}
---
CLI Usage
Create or update your PWA manifest interactively:
`bash
npx @polterware/pwa init
`The CLI will:
1. Look for existing
manifest.json and use values as placeholders
2. Ask for app name, colors, icons, etc.
3. Create/update the manifest fileOptions:
`bash
npx @polterware/pwa init --manifest-path custom/path/manifest.json
`---
API Reference
$3
####
detectInstalled(): booleanDetects if the PWA is installed by checking
display-mode: standalone and navigator.standalone (iOS).`typescript
const isInstalled = detectInstalled();
`####
detectPlatform(): PlatformDetects the current platform.
`typescript
const platform = detectPlatform();
// Returns: 'ios' | 'android' | 'macos_safari' | 'desktop' | 'other'
`####
getInstallInstructions(platform, config?): InstallInstructionsReturns platform-specific install instructions. Supports built-in locales or custom config.
`typescript
// Using built-in locale (en, pt-BR, es)
const instructions = getInstallInstructions("ios", { locale: "pt-BR" });// Using custom config
const instructions = getInstallInstructions("ios", {
title: "Install My App",
subtitle: "Add to your home screen",
buttonText: "Install",
gotItText: "Got it!",
});
// Using locale with overrides
const instructions = getInstallInstructions("ios", {
locale: "pt-BR",
overrides: { title: "Meu App" },
});
`Available Locales:
| Locale | Language |
| ------- | ------------------- |
|
en | English (default) |
| pt-BR | Portuguese (Brazil) |
| es | Spanish |$3
####
usePWA(): UsePWAReturnRecommended - Combined hook for PWA status and platform.
`typescript
const { isInstalled, platform } = usePWA();
`####
useIsInstalled(): booleanSimple hook for PWA installation status.
`typescript
const isInstalled = useIsInstalled();
`####
usePlatform(): PlatformHook for platform detection.
`typescript
const platform = usePlatform();
`$3
####
InstallPromptUI-agnostic component with render props for complete customization.
| Prop | Type | Default | Description |
| -------------------- | ----------------------------- | ------- | ---------------------------------------- |
|
renderTrigger | (instructions) => ReactNode | - | Render function for trigger button |
| renderInstructions | (instructions) => ReactNode | - | Render function for instructions |
| children | ReactNode | - | Fallback if renderTrigger not provided |
| instructionsConfig | object | - | Override default instruction texts |
| locale | 'en' \| 'pt-BR' \| 'es' | - | Use built-in translations for locale |
| hideIfInstalled | boolean | true | Hide component if PWA is installed |---
Types
`typescript
type Platform = "ios" | "macos_safari" | "android" | "desktop" | "other";interface InstallInstruction {
number: number;
title: string;
description: string;
}
interface InstallInstructions {
platform: Platform;
steps: InstallInstruction[];
title: string;
subtitle: string;
buttonText: string;
gotItText: string;
}
interface UsePWAReturn {
isInstalled: boolean;
platform: Platform;
}
`---
Examples
$3
`tsx
// app/components/InstallButton.tsx
"use client";import { usePWA, InstallPrompt } from "@polterware/pwa/react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { useState } from "react";
export function InstallButton() {
const { isInstalled, platform } = usePWA();
const [open, setOpen] = useState(false);
if (isInstalled) return null;
return (
instructionsConfig={{
title: "Install My App",
subtitle: "Add to your home screen for quick access",
}}
renderTrigger={(instructions) => (
)}
renderInstructions={(instructions) => (
)}
/>
);
}
``---
- Node.js: >= 16.0.0
- React (for hooks): >= 16.8.0
MIT License - see the LICENSE file for details.