React Native permissions generator

React Native save to the photo library permission

Writing an image or video the app produced back into the device library is a separate grant from reading it. Android uses WRITE_EXTERNAL_STORAGE on older releases (scoped storage makes it unnecessary on Android 10 and later for the app's own media), and iOS uses NSPhotoLibraryAddUsageDescription, an add-only key that does not expose the existing library.

expo-media-library declares both and its saveToLibraryAsync performs the write after requestPermissionsAsync. Prefer the add-only iOS key over the full read/write one whenever the app only saves: the narrower prompt is easier for users to accept and for reviewers to approve.

Save to the photo library at a glance

Android grants
android.permission.WRITE_EXTERNAL_STORAGE
iOS Info.plist key
NSPhotoLibraryAddUsageDescription
Expo package
expo-media-library
Config plugin
expo-media-library
What it enables
Write images or video the app produced back to the device.
What the user agrees to
Add photos and videos to the device library

The declarations, for Expo and the bare workflow

Expo config

app.json
{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSPhotoLibraryAddUsageDescription": "TODO: why this app saves media to your library."
      }
    },
    "android": {
      "permissions": [
        "android.permission.WRITE_EXTERNAL_STORAGE"
      ]
    },
    "plugins": [
      "expo-router",
      "expo-media-library"
    ]
  }
}

Prebuild writes these into the native projects; the config plugin is what makes the package's native code part of the build.

Bare workflow, Android

android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Bare workflow, iOS

ios/<App>/Info.plist
<key>NSPhotoLibraryAddUsageDescription</key>
<string>TODO: why this app saves media to your library.</string>

The TODO is deliberate: the usage description is shown in the consent prompt and App Review rejects boilerplate.

Install the library

terminal
npx expo install expo-media-library

Save to the photo library permission, answered

The longer version is in the guide React Native permissions that satisfy both stores.

What permission does React Native need for save to the photo library?
On Android, declare android.permission.WRITE_EXTERNAL_STORAGE in AndroidManifest.xml (or expo.android.permissions in app.json). On iOS, add NSPhotoLibraryAddUsageDescription to Info.plist (or expo.ios.infoPlist) with a sentence explaining why — the user reads it in the consent prompt. expo-media-library exposes the runtime request.
Do I still have to request save to the photo library at runtime?
Yes. The declaration only makes the request possible. The first time the feature is used, call the request API from expo-media-library; the operating system shows the prompt ("Add photos and videos to the device library") and remembers the answer. A declared but never requested permission does nothing, and a requested but never declared one fails.
Why was my app rejected over the save to the photo library permission?
Most often the NSPhotoLibraryAddUsageDescription string: App Review rejects a missing one at once and a vague or boilerplate one frequently. Write what the app does with the data in your own words. Google Play reviews the declaration against the app's visible features, so a grant no screen uses is also a finding.

Declare every feature the app uses

The React Native permissions generator builds the complete set from the same catalogue — tick each device feature and copy the paired Android grants and iOS usage descriptions, the Expo app.json fragment and the install line together. In the Nodlume workspace the declarations come from the screens themselves: a screen that uses the camera is what adds the camera permission to the Expo Router project it exports.

Open the generator

Other React Native permissions

We'd like to use Google cookies to understand how Nodlume is used and to measure our advertising. Nothing loads until you choose, and declining does not affect anything in the app.