Handling Media Access with expo-image-picker
Learn how to implement expo-image-picker with a focus on permission handling, preventing memory crashes through compression, and managing the 'cancelled' state to avoid runtime errors.
02 Apr 2026, 23:52 UTC

The Core Challenge: Permissions and State
\nImplementing an image picker in Expo requires more than calling a function to open the gallery. The primary point of failure is the gap between requesting system permissions and handling the user\'s interaction with the native UI. If you attempt to launch the library without a granted permission state, the app may crash on iOS or fail silently on Android.
\nThe reliable workflow is: Check/Request Permission → Launch Picker → Validate Result State.
\nImplementation Strategy
\nTo implement this, you need the expo-image-picker library. This example assumes a managed workflow using Expo SDK 48 or newer. It demonstrates a robust pattern that handles both permission denial and the user canceling the selection process.
import * as ImagePicker from 'expo-image-picker';\nimport { useState } from 'react';\nimport { Button, Image, View, Alert } from 'react-native';\n\nexport default function ImageUpload() {\n const [image, setImage] = useState(null);\n\n const pickImage = async () => {\n const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();\n if (status !== 'granted') {\n Alert.alert('Permission Denied', 'We need gallery access to upload photos.');\n return;\n }\n\n let result = await ImagePicker.launchImageLibraryAsync({\n mediaTypes: ImagePicker.MediaTypeOptions.Images,\n allowsEditing: true,\n aspect: [4, 3],\n quality: 0.7,\n });\n\n if (!result.canceled) {\n setImage(result.assets[0].uri);\n }\n };\n\n return (\n \n \n {image && }\n \n );\n}\n\nConfiguration Breakdown
\n| Option | \nImpact | \nRisk | \n
|---|---|---|
allowsEditing | \n Opens a native crop/rotate tool. | \nAdds an extra step for the user; may vary by OS. | \n
quality | \n Compresses the image 0.0 to 1.0. | \nToo low causes pixelation; too high causes OOM crashes. | \n
mediaTypes | \n Filters for Images, Videos, or All. | \nSelecting All requires more complex validation of the resulting URI. | \n
Platform-Specific Requirements
\nBecause expo-image-picker interacts with native hardware, you must configure your app.json to describe why the app needs these permissions. Without these descriptions, the app will crash immediately upon the permission request on iOS.
// app.json\n{\n "expo": {\n "plugins": [\n [\n "expo-image-picker",\n {\n "photosPermission": "The app accesses your photos to let you upload a profile picture.\"\n }\n ]\n ]\n }\n}\n\nAndroid API 33+ Considerations
\nFor Android 13 and above, the generic READ_EXTERNAL_STORAGE permission is deprecated. Expo handles this abstraction, but if you are using a bare workflow or custom native modules, ensure you explicitly declare READ_MEDIA_IMAGES in your AndroidManifest.xml to avoid permission denials on modern devices.
\nCommon Engineering Mistakes
\n- \n
- Ignoring the canceled flag: Developers often try to access result.uri immediately. In newer versions the result is returned as an array in result.assets. If the user hits Cancel, result.canceled is true and assets is empty. Accessing assets[0] without checking the flag will throw a runtime error. \n
- Overlooking Memory Pressure: Loading a 12MP raw photo into a React Native Image component without using the quality setting in the picker can lead to memory-pressure crashes, especially on low-end Android devices. \n
- Assuming Permission is Permanent: Users can revoke permissions in system settings at any time. Always call requestMediaLibraryPermissionsAsync or getMediaLibraryPermissionsAsync before launching the picker, rather than checking once at app startup. \n
Verification and Testing
\nTo verify the implementation, perform these three checks on a physical device:
\n- \n
- First Launch: Ensure the system permission dialog appears and the picker opens only after clicking Allow. \n
- Cancellation: Open the picker and press the back button or Cancel. Verify the app does not crash and remains in its previous state. \n
- Revocation: Go to System Settings → App Permissions, revoke the gallery access, and return to the app. Verify the app re-requests permission correctly. \n
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.