Skip to Content
react-native-kernel is in active development (v0.0.0) — APIs may change before v1.
Docskernel/permissions

kernel/permissions

usePermission() — one API for checking and requesting camera, location, notifications, and storage permissions on both platforms, plus a PermissionDeniedFallback UI component for the “please grant this” state.

import { usePermission, PermissionDeniedFallback } from 'react-native-kernel/permissions';

usePermission(type, options?)

import { usePermission, PermissionDeniedFallback } from 'react-native-kernel/permissions'; function CameraScreen() { const camera = usePermission('camera'); if (!camera.isGranted) { return ( <PermissionDeniedFallback type="camera" status={camera.status} onRequest={camera.request} onOpenSettings={camera.openSettings} /> ); } return <CameraView />; }

type is one of 'camera' | 'location' | 'notifications' | 'storage'.

The four-state status model

Most permission libraries collapse “never asked” and “permanently denied” into the same boolean. That’s not enough to build correct UI with — you need to know whether calling request() will show a dialog at all.

StatusMeaningWhat request() does
grantedUsable right nowNo-op, resolves 'granted' immediately
deniedNot granted yetShows the system dialog
blockedThe OS won’t prompt againNo dialog shown — only openSettings() helps from here
unavailableNot supported on this platform/device—

iOS shows its permission dialog at most once per app install. The moment the user answers it — even the first “Don’t Allow” — there’s no API to show it again. So on iOS, a fresh denial is reported as blocked immediately, not as a re-askable denied, because that’s what’s actually true: calling request() again would silently do nothing.

Android is murkier: shouldShowRequestPermissionRationale() returns false both for “never asked” and for “permanently denied (‘Don’t ask again’)” — they’re indistinguishable from that API alone. This module works around it by remembering, in a small local flag per permission type, whether it has asked before — so it can tell the two states apart correctly.

Options

OptionTypeDefault
checkOnMountbooleantrue — checks status once when the hook mounts

Return value

FieldTypeNotes
statusPermissionStatus
isGrantedbooleanstatus === 'granted'
isCheckingbooleanTrue during check()/request()
check()() => Promise<PermissionStatus>Re-reads status — never shows UI
request()() => Promise<PermissionStatus>Shows the system dialog, if one would appear
openSettings()() => Promise<void>Opens the app’s system settings screen

<PermissionDeniedFallback />

A small, unstyled-but-functional fallback card — renders null once status is 'granted'.

<PermissionDeniedFallback type="location" status={location.status} onRequest={location.request} onOpenSettings={location.openSettings} />

Shows a “Grant Permission” button when request() would still show a dialog, or an “Open Settings” button once the status is blocked.

Permissions you need to declare

This module never adds camera/location/notification/photo permissions to your app’s manifest or Info.plist for you — unlike kernel/system’s network permissions, these are sensitive and opt-in per feature. See Installation for exactly what to add for each type you use.

Next: kernel/media.

Last updated on