hybridweb-permission-checker
v0.0.1
Published
Unified permission status checker (location / geolocation, notification) for hybrid apps on Web, PWA, Capacitor (iOS / Android) and Electron. Never throws, never prompts.
Downloads
316
Maintainers
Keywords
Readme
hybridweb-permission-checker
Unified permission status checker for hybrid apps running on Web (browser / PWA), Capacitor (iOS / Android) and Electron (desktop).
Check location (geolocation) and notification permission state with a single cross-platform API that always resolves to
"granted" | "denied" | "prompt" | "unsupported". It never throws and never shows a permission prompt.
Every platform reads permissions in a different way. The browser uses navigator.permissions.query and Notification.permission,
Capacitor plugins use checkPermissions(), and the states differ too ("default", "prompt-with-rationale", ...).
This package hides those differences. Each platform lives in its own subpath, so your web bundle never pulls in Capacitor code
(tree-shakable, ESM, TypeScript).
Scope: this package only checks permission state. Requesting a permission (showing the prompt) or reading location coordinates is out of scope.
Use cases
- Pre-permission screens: on
prompt, show your own "why we need location" explainer before triggering the native prompt; ondenied, guide users to system settings. - Settings pages: show "Notifications: on / off" with the same code on web, iOS, Android and desktop.
- Feature gating: hide location-based features when the result is
unsupported(e.g. an Android WebView withoutwindow.Notification).
Install
npm install hybridweb-permission-checker
# or
pnpm add hybridweb-permission-checkerIf you use the Capacitor subpaths (*/capacitor), also install the peer dependencies:
pnpm add @capacitor/core @capacitor/geolocation @capacitor/local-notificationsUsage
Detect the platform in your app and dynamically import the matching subpath:
import type { PermissionStatus } from "hybridweb-permission-checker";
type Platform = "web" | "desktop" | "native";
export async function checkLocationPermission(platform: Platform): Promise<PermissionStatus> {
const mod =
platform === "web"
? await import("hybridweb-permission-checker/location/web")
: platform === "desktop"
? await import("hybridweb-permission-checker/location/electron")
: await import("hybridweb-permission-checker/location/capacitor"); // iOS / Android
return mod.check();
}
const status = await checkLocationPermission("web");
if (status === "prompt") {
// show your own explainer, then request the permission
}API
Subpaths
Every subpath exports the same function: check(): Promise<PermissionStatus>.
| Subpath | Platform | Underlying API |
| --- | --- | --- |
| hybridweb-permission-checker/location/web | Browser / PWA | navigator.permissions.query({ name: "geolocation" }) |
| hybridweb-permission-checker/location/capacitor | iOS / Android | Geolocation.checkPermissions() from @capacitor/geolocation |
| hybridweb-permission-checker/location/electron | Electron renderer | Same as web (Chromium) |
| hybridweb-permission-checker/notification/web | Browser / PWA | Notification.permission |
| hybridweb-permission-checker/notification/capacitor | iOS / Android | LocalNotifications.checkPermissions() from @capacitor/local-notifications |
| hybridweb-permission-checker/notification/electron | Electron renderer | Same as web (Chromium) |
The root entry (hybridweb-permission-checker) exports types only.
Types
type PermissionStatus = "granted" | "denied" | "prompt" | "unsupported";
type PermissionName = "location" | "notification";granted: alloweddenied: blockedprompt: not asked yet (requesting may show a prompt). Web"default"and Android"prompt-with-rationale"map here.unsupported: no API to read this permission in the current environment
check() never throws. It always resolves to one of the four values above.
Note: Electron location
location/electron reads the renderer state, but it only becomes granted when the app shell (main process) allows it.
This package does not handle that:
- main process: approve
"geolocation"insession.setPermissionRequestHandler(...) - OS entitlements:
NSLocationUsageDescriptionin macOSInfo.plist, Windows location privacy settings
Without these, check() always returns prompt or denied.
The same code runs on macOS, Windows and Linux with no OS branching. On Linux, Chromium has no built-in OS location
service and relies on a network provider, so granted is the least reliable there.
License
MIT
