# react-native-permissions: one permissions API for iOS, Android and Windows

> react-native-permissions wraps the platform permission dialogs behind a single JavaScript API and a per-platform setup step. It fits apps that need camera, location or notification access and cannot accept the defaults of an Expo-managed build.

**zoontek/react-native-permissions** — An unified permissions API for React Native on iOS, Android and Windows.

- Repository: https://github.com/zoontek/react-native-permissions
- Stars: 4,376 · Forks: 845
- Language: Objective-C++
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/zoontek-react-native-permissions

## What react-native-permissions replaces

React Native ships no permission API. On iOS you would call into a native module or write one; on Android you would check ContextCompat.checkSelfPermission and handle the request callback yourself; on Windows you would use a third code path. react-native-permissions gives all three a single surface, so a screen that asks for camera access does not branch on Platform.OS just to reach the dialog. The package describes itself as "An unified permissions API for React Native on iOS, Android and Windows", and the repository layout backs that up: separate ios/, android/ and windows/ directories behind one JavaScript entry point.

The audience is specific. This is for teams building a bare React Native app, or an Expo app that has moved to a development build, who need to know the state of a permission before showing a feature. It is not a UI library: it does not render a rationale screen or a settings prompt for you. It answers whether a permission is granted, denied, blocked or limited, and it can open the system settings page when the user has permanently refused.

## How the JavaScript API reaches the native dialogs

The package publishes two module formats. package.json points "main" at ./dist/commonjs/index.js and "module" at ./dist/module/index.js, with types under ./dist/typescript. That means the same import works in a Metro-bundled app regardless of whether the toolchain resolves CommonJS or ESM.

Beyond the root export there are three subpath exports. ./expo is a separate entry for Expo projects, ./mock provides a mock implementation for tests, and ./scripts/setup.rb is the Ruby script the iOS setup depends on. The mock entry matters more than it looks: permission state is otherwise controlled by the operating system, and a test suite that cannot set that state has to skip the code paths that matter.

On iOS the mechanism is a Podfile script rather than a runtime scan. Nothing is compiled in by default. The README is explicit: "By default, no permissions are available." You call setup_permissions with the list you want, run pod install, and only those permissions exist in the build. On Android the equivalent switch is the manifest: you add <uses-permission> entries yourself, and the README warns to "Keep only the permissions used in your app". The library reads the platform state; it does not declare anything on your behalf.

## Installing react-native-permissions and asking for camera access

Install from npm or Yarn. The README gives both forms:

```bash
npm i -S react-native-permissions
# --- or ---
yarn add react-native-permissions
```

On iOS, the Podfile needs a generic node_require helper before the package's setup script can be required. The README shows the transformation: replace the inline require of react-native/scripts/react_native_pods.rb with a def node_require(script) function, then require both scripts through it.

```ruby
def node_require(script)
  require Pod::Executable.execute_command('node', ['-p',
    "require.resolve(
      '#{script}',
      {paths: [process.argv[1]]},
    )", __dir__]).strip
end

node_require('react-native/scripts/react_native_pods.rb')
node_require('react-native-permissions/scripts/setup.rb')
```

Then call setup_permissions with only the permissions you need. The README ships the full list commented out; uncommenting Camera is the minimum for a camera feature.

```ruby
setup_permissions([
  # 'AppTrackingTransparency',
  # 'Bluetooth',
  # 'Calendars',
  # 'Camera',
  # 'Contacts',
  # 'LocationWhenInUse',
  # 'Microphone',
  # 'Notifications',
  # 'PhotoLibrary',
])
```

Run pod install in ios/ afterwards. The README notes it "must be re-executed each time you update this config", so treat the Podfile as the source of truth for which permissions exist. Finally add the matching usage description to Info.plist, for example NSCameraUsageDescription with a reason string. The README repeats the warning there too: keep only the permissions specified in setup_permissions.

On Android, add the manifest entries for the permissions your app actually uses:

```xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
```

With both platforms configured, a check for camera access returns one of the library's status values, and a request triggers the system dialog. If the user has permanently denied it, the library can open the app's settings page, which is the recovery path the README's related searches refer to as open settings.

## The setup surface is the library's real cost

The unified API is the easy part. The configuration is where projects get stuck. On iOS, permissions are opt-in at build time, so forgetting to uncomment 'PhotoLibrary' in setup_permissions and re-run pod install produces a build where that permission simply is not there. There is no runtime error that names the missing entry; you get a status the app cannot act on. The same class of mistake exists on Android, where the manifest is hand-edited and the README asks you to keep it minimal.

Two other constraints are worth stating plainly. Windows support is bounded: the README says only builds 18362 and later are supported. If your product still ships to older Windows targets, the third platform in the tagline does not apply to you. And the support policy is narrow: the library follows the React Native releases support policy and supports "the latest version, and the two previous minor series". A project pinned to an older React Native release is outside that window, and nothing in the README describes a long-term support branch.

The README does not document rollback: there is no described way to undo a setup_permissions entry other than removing it and re-running pod install. It also does not describe what happens when a permission is requested on a platform where it was never configured.

## Compared with Expo's permission helpers

The closest alternative for many teams is the permission module that ships with Expo. The difference is the install model, not the call shape. Expo's helpers are part of the Expo SDK and work in a managed workflow without touching a Podfile; react-native-permissions expects you to own the native configuration. Its ./expo export exists precisely for projects that have left the managed path but still want the library's API.

That trade is real in both directions. If you stay in Expo Go, the Podfile step is unavailable to you and this package is the wrong tool. If you have a bare app and need a permission Expo's SDK does not expose, or you want the same status values on Windows, the Expo module does not cover it and this one does. The library also ships a ./mock entry, which the Expo helpers do not advertise, and that is the practical reason to pick it for a codebase with a serious test suite.

## Maintenance, licence and upgrade cost

The repository is not archived, and the last push was on 2026-09-14, the same day as the 5.6.2 release. The two releases before it, 5.6.1 and 5.6.0, landed on 2026-07-23 and 2026-06-16. That cadence is consistent with the stated support policy: the maintainers track React Native's release train rather than promising a fixed API.

The licence is MIT, declared in package.json and in the LICENSE file at the repository root. MIT is permissive, so the practical implication for most teams is attribution rather than a redistribution obligation. That is a description of the licence text, not legal advice; if your organisation has a policy on dependency licences, the file to read is LICENSE.

Upgrade cost concentrates in two places. A React Native upgrade can push you outside the supported window, and the Podfile transformation shown in the README has to survive whatever the new React Native template does to that file. When you add a permission later, the sequence is always the same: edit setup_permissions, run pod install, add the Info.plist key, and add the Android manifest entry. Skipping the pod install step is the failure mode the README calls out directly.

## Conclusion

Adopt it if your app is a bare or prebuild React Native project that needs permission checks on iOS and Android and you are willing to keep the Podfile's setup_permissions list and the Android manifest in sync by hand. Do not adopt it if you want the Expo Go workflow, since the iOS side depends on a Podfile and a pod install. Before committing, verify three things: that your React Native version falls inside the supported window (the latest release and the two previous minor series), that every permission you list in setup_permissions has a matching usage description in Info.plist, and that your Android target build is recent enough for the manifest entries you add.

## FAQ

### How do I install react-native-permissions?

Install the package with npm i -S react-native-permissions or yarn add react-native-permissions, then configure each platform: require the setup script in your Podfile and call setup_permissions on iOS, and add the wanted <uses-permission> entries to AndroidManifest.xml on Android.

### What is React Native mainly used for?

The README does not describe React Native itself, only that react-native-permissions follows the React Native releases support policy and supports the latest version plus the two previous minor series.

### Is React Native still relevant in 2026?

The repository makes no such claim. What it does show is continued releases for this package in 2026, with 5.6.2 published on 2026-09-14.

### Is Netflix using React Native?

The repository does not mention Netflix or any other adopter of React Native, so this cannot be answered from what it documents.

### What are the disadvantages of React Native?

The README does not discuss React Native's disadvantages in general. The project-specific constraint it does state is that only the latest React Native version and the two previous minor series are supported.

## Sources

- [Issues](https://github.com/zoontek/react-native-permissions/issues)
- [License: MIT](https://github.com/zoontek/react-native-permissions/blob/master/LICENSE)
- [README](https://github.com/zoontek/react-native-permissions/blob/master/README.md)
- [Releases](https://github.com/zoontek/react-native-permissions/releases)
- [zoontek/react-native-permissions on GitHub](https://github.com/zoontek/react-native-permissions)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/zoontek-react-native-permissions
