A React Native module that allows you to use native UI to select media from the device library or directly from the camera
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
React Native Image Picker provides native UI access for selecting photos and videos from device libraries or directly from the camera. It offers cross-platform support for iOS, Android, and web with comprehensive options for media selection including quality control, size constraints, format preferences, and multiple selection capabilities.
npm install react-native-image-pickerimport { launchCamera, launchImageLibrary } from "react-native-image-picker";For CommonJS:
const { launchCamera, launchImageLibrary } = require("react-native-image-picker");import { launchCamera, launchImageLibrary, ImagePickerResponse } from "react-native-image-picker";
// Launch camera to take a photo
const cameraOptions = { mediaType: 'photo' as const, quality: 0.8 };
const cameraResult = await launchCamera(cameraOptions);
if (cameraResult.assets && cameraResult.assets.length > 0) {
const asset = cameraResult.assets[0];
console.log('Image URI:', asset.uri);
}
// Launch image library to select photos
const libraryOptions = { mediaType: 'photo' as const, selectionLimit: 3 };
const libraryResult = await launchImageLibrary(libraryOptions);
if (libraryResult.assets) {
libraryResult.assets.forEach((asset, index) => {
console.log(`Selected image ${index + 1}:`, asset.uri);
});
}React Native Image Picker is built around platform-specific implementations:
launchCamera and launchImageLibrary functions work consistently across platformsPlatform.OSLaunches the device camera to capture photos or videos with extensive configuration options.
/**
* Launch camera to take photo or video
* @param options - Camera configuration options
* @param callback - Optional callback function for response
* @returns Promise resolving to ImagePickerResponse
*/
function launchCamera(
options: CameraOptions,
callback?: Callback
): Promise<ImagePickerResponse>;
interface CameraOptions extends OptionsCommon {
/** Maximum video duration in seconds */
durationLimit?: number;
/** Save captured media to device photos (requires permissions on Android <29) */
saveToPhotos?: boolean;
/** Camera type selection */
cameraType?: CameraType;
}Launches the device image/video library for media selection with support for multiple items and filtering.
/**
* Launch gallery to pick image or video
* @param options - Image library configuration options
* @param callback - Optional callback function for response
* @returns Promise resolving to ImagePickerResponse
*/
function launchImageLibrary(
options: ImageLibraryOptions,
callback?: Callback
): Promise<ImagePickerResponse>;
interface ImageLibraryOptions extends OptionsCommon {
/** Number of items to select (0 = unlimited on iOS ≥14, Android ≥13) */
selectionLimit?: number;
/** Array of allowed MIME types (Android only) */
restrictMimeTypes?: string[];
}interface ImagePickerResponse {
/** True if user cancelled the operation */
didCancel?: boolean;
/** Error code if operation failed */
errorCode?: ErrorCode;
/** Error message for debugging */
errorMessage?: string;
/** Array of selected media assets */
assets?: Asset[];
}
interface Asset {
/** Base64 string of image (photos only, if includeBase64: true) */
base64?: string;
/** File URI in app cache storage */
uri?: string;
/** Asset width in pixels */
width?: number;
/** Asset height in pixels */
height?: number;
/** Original file path (Android only) */
originalPath?: string;
/** File size in bytes */
fileSize?: number;
/** MIME type of the file */
type?: string;
/** Name of the file */
fileName?: string;
/** Video duration in seconds (video only) */
duration?: number;
/** Video bitrate in bits/sec (Android only) */
bitrate?: number;
/** Asset timestamp (requires includeExtra: true) */
timestamp?: string;
/** Local identifier (requires includeExtra: true) */
id?: string;
}interface OptionsCommon {
/** Type of media to select */
mediaType: MediaType;
/** Maximum width for image resizing */
maxWidth?: number;
/** Maximum height for image resizing */
maxHeight?: number;
/** Photo quality level (0-1) */
quality?: PhotoQuality;
/** Video quality setting (platform-specific) */
videoQuality?: AndroidVideoOptions | iOSVideoOptions;
/** Include base64 string in response (avoid for large images) */
includeBase64?: boolean;
/** Include extra metadata requiring permissions */
includeExtra?: boolean;
/** Convert selected video to MP4 (iOS only) */
formatAsMp4?: boolean;
/** Picker presentation style (iOS only) */
presentationStyle?:
| 'currentContext'
| 'fullScreen'
| 'pageSheet'
| 'formSheet'
| 'popover'
| 'overFullScreen'
| 'overCurrentContext';
/** Asset representation mode for HEIC/HEIF handling */
assetRepresentationMode?: 'auto' | 'current' | 'compatible';
}/** Callback function type for picker responses */
type Callback = (response: ImagePickerResponse) => any;
/** Media type selection */
type MediaType = 'photo' | 'video' | 'mixed';
/** Camera type selection */
type CameraType = 'back' | 'front';
/** Photo quality levels */
type PhotoQuality =
| 0 | 0.1 | 0.2 | 0.3 | 0.4 | 0.5
| 0.6 | 0.7 | 0.8 | 0.9 | 1;
/** Video quality options for Android */
type AndroidVideoOptions = 'low' | 'high';
/** Video quality options for iOS */
type iOSVideoOptions = 'low' | 'medium' | 'high';
/** Error codes for failed operations */
type ErrorCode = 'camera_unavailable' | 'permission' | 'others';| Feature | iOS | Android | Web |
|---|---|---|---|
| Photo capture/selection | ✅ | ✅ | ✅ |
| Video capture/selection | ✅ | ✅ | ❌ |
| Multiple selection | ✅ | ✅ | ✅ |
| Quality control | ✅ | ✅ | ❌ |
| Camera type selection | ✅ | ✅ | ❌ |
| Base64 encoding | ✅ | ✅ | ✅ |
| Save to photos | ✅ | ✅ | ❌ |
| MIME type restrictions | ❌ | ✅ | ❌ |
import { launchCamera, CameraOptions } from "react-native-image-picker";
const options: CameraOptions = {
mediaType: 'photo',
quality: 0.8,
maxWidth: 1000,
maxHeight: 1000,
cameraType: 'back',
saveToPhotos: true,
includeBase64: false,
};
try {
const result = await launchCamera(options);
if (result.didCancel) {
console.log('User cancelled camera');
} else if (result.errorMessage) {
console.error('Camera Error:', result.errorMessage);
} else if (result.assets && result.assets[0]) {
const asset = result.assets[0];
console.log('Captured image:', {
uri: asset.uri,
width: asset.width,
height: asset.height,
fileSize: asset.fileSize,
});
}
} catch (error) {
console.error('Camera launch failed:', error);
}import { launchImageLibrary, ImageLibraryOptions } from "react-native-image-picker";
const options: ImageLibraryOptions = {
mediaType: 'photo',
selectionLimit: 5, // Allow up to 5 images
quality: 0.9,
includeBase64: false,
};
const result = await launchImageLibrary(options);
if (result.assets) {
console.log(`Selected ${result.assets.length} images:`);
result.assets.forEach((asset, index) => {
console.log(`Image ${index + 1}:`, {
uri: asset.uri,
fileName: asset.fileName,
fileSize: asset.fileSize,
type: asset.type,
});
});
}import { launchCamera, CameraOptions } from "react-native-image-picker";
const videoOptions: CameraOptions = {
mediaType: 'video',
videoQuality: 'high',
durationLimit: 60, // 60 seconds max
cameraType: 'back',
};
const result = await launchCamera(videoOptions);
if (result.assets && result.assets[0]) {
const video = result.assets[0];
console.log('Recorded video:', {
uri: video.uri,
duration: video.duration,
fileSize: video.fileSize,
type: video.type,
});
}import { launchImageLibrary, ImagePickerResponse } from "react-native-image-picker";
// Using callback instead of await
launchImageLibrary(
{ mediaType: 'photo', selectionLimit: 1 },
(response: ImagePickerResponse) => {
if (response.assets && response.assets[0]) {
console.log('Selected image URI:', response.assets[0].uri);
}
}
);import { launchCamera, ErrorCode } from "react-native-image-picker";
const result = await launchCamera({ mediaType: 'photo' });
if (result.errorCode) {
switch (result.errorCode) {
case 'camera_unavailable':
console.error('Camera not available on this device');
break;
case 'permission':
console.error('Camera permission denied');
break;
case 'others':
console.error('Other error:', result.errorMessage);
break;
}
}