A React Native module that allows you to use native UI to select media from the device library or directly from the camera
npx @tessl/cli install tessl/npm-react-native-image-picker@8.2.00
# React Native Image Picker
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: react-native-image-picker
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install react-native-image-picker`
10
11
## Core Imports
12
13
```typescript
14
import { launchCamera, launchImageLibrary } from "react-native-image-picker";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { launchCamera, launchImageLibrary } = require("react-native-image-picker");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import { launchCamera, launchImageLibrary, ImagePickerResponse } from "react-native-image-picker";
27
28
// Launch camera to take a photo
29
const cameraOptions = { mediaType: 'photo' as const, quality: 0.8 };
30
const cameraResult = await launchCamera(cameraOptions);
31
32
if (cameraResult.assets && cameraResult.assets.length > 0) {
33
const asset = cameraResult.assets[0];
34
console.log('Image URI:', asset.uri);
35
}
36
37
// Launch image library to select photos
38
const libraryOptions = { mediaType: 'photo' as const, selectionLimit: 3 };
39
const libraryResult = await launchImageLibrary(libraryOptions);
40
41
if (libraryResult.assets) {
42
libraryResult.assets.forEach((asset, index) => {
43
console.log(`Selected image ${index + 1}:`, asset.uri);
44
});
45
}
46
```
47
48
## Architecture
49
50
React Native Image Picker is built around platform-specific implementations:
51
52
- **Cross-Platform API**: Unified `launchCamera` and `launchImageLibrary` functions work consistently across platforms
53
- **Platform Detection**: Automatically routes to native (iOS/Android) or web implementations based on `Platform.OS`
54
- **Native Bridge**: Uses React Native's TurboModule system for optimal performance on native platforms
55
- **Web Implementation**: Uses browser APIs (getUserMedia, file input) for web platform support
56
- **Promise/Callback Support**: Functions return promises but also accept optional callback functions for flexibility
57
58
## Capabilities
59
60
### Camera Launch
61
62
Launches the device camera to capture photos or videos with extensive configuration options.
63
64
```typescript { .api }
65
/**
66
* Launch camera to take photo or video
67
* @param options - Camera configuration options
68
* @param callback - Optional callback function for response
69
* @returns Promise resolving to ImagePickerResponse
70
*/
71
function launchCamera(
72
options: CameraOptions,
73
callback?: Callback
74
): Promise<ImagePickerResponse>;
75
76
interface CameraOptions extends OptionsCommon {
77
/** Maximum video duration in seconds */
78
durationLimit?: number;
79
/** Save captured media to device photos (requires permissions on Android <29) */
80
saveToPhotos?: boolean;
81
/** Camera type selection */
82
cameraType?: CameraType;
83
}
84
```
85
86
### Image Library Launch
87
88
Launches the device image/video library for media selection with support for multiple items and filtering.
89
90
```typescript { .api }
91
/**
92
* Launch gallery to pick image or video
93
* @param options - Image library configuration options
94
* @param callback - Optional callback function for response
95
* @returns Promise resolving to ImagePickerResponse
96
*/
97
function launchImageLibrary(
98
options: ImageLibraryOptions,
99
callback?: Callback
100
): Promise<ImagePickerResponse>;
101
102
interface ImageLibraryOptions extends OptionsCommon {
103
/** Number of items to select (0 = unlimited on iOS ≥14, Android ≥13) */
104
selectionLimit?: number;
105
/** Array of allowed MIME types (Android only) */
106
restrictMimeTypes?: string[];
107
}
108
```
109
110
## Types
111
112
### Response and Asset Types
113
114
```typescript { .api }
115
interface ImagePickerResponse {
116
/** True if user cancelled the operation */
117
didCancel?: boolean;
118
/** Error code if operation failed */
119
errorCode?: ErrorCode;
120
/** Error message for debugging */
121
errorMessage?: string;
122
/** Array of selected media assets */
123
assets?: Asset[];
124
}
125
126
interface Asset {
127
/** Base64 string of image (photos only, if includeBase64: true) */
128
base64?: string;
129
/** File URI in app cache storage */
130
uri?: string;
131
/** Asset width in pixels */
132
width?: number;
133
/** Asset height in pixels */
134
height?: number;
135
/** Original file path (Android only) */
136
originalPath?: string;
137
/** File size in bytes */
138
fileSize?: number;
139
/** MIME type of the file */
140
type?: string;
141
/** Name of the file */
142
fileName?: string;
143
/** Video duration in seconds (video only) */
144
duration?: number;
145
/** Video bitrate in bits/sec (Android only) */
146
bitrate?: number;
147
/** Asset timestamp (requires includeExtra: true) */
148
timestamp?: string;
149
/** Local identifier (requires includeExtra: true) */
150
id?: string;
151
}
152
```
153
154
### Options and Configuration Types
155
156
```typescript { .api }
157
interface OptionsCommon {
158
/** Type of media to select */
159
mediaType: MediaType;
160
/** Maximum width for image resizing */
161
maxWidth?: number;
162
/** Maximum height for image resizing */
163
maxHeight?: number;
164
/** Photo quality level (0-1) */
165
quality?: PhotoQuality;
166
/** Video quality setting (platform-specific) */
167
videoQuality?: AndroidVideoOptions | iOSVideoOptions;
168
/** Include base64 string in response (avoid for large images) */
169
includeBase64?: boolean;
170
/** Include extra metadata requiring permissions */
171
includeExtra?: boolean;
172
/** Convert selected video to MP4 (iOS only) */
173
formatAsMp4?: boolean;
174
/** Picker presentation style (iOS only) */
175
presentationStyle?:
176
| 'currentContext'
177
| 'fullScreen'
178
| 'pageSheet'
179
| 'formSheet'
180
| 'popover'
181
| 'overFullScreen'
182
| 'overCurrentContext';
183
/** Asset representation mode for HEIC/HEIF handling */
184
assetRepresentationMode?: 'auto' | 'current' | 'compatible';
185
}
186
```
187
188
### Enumeration Types
189
190
```typescript { .api }
191
/** Callback function type for picker responses */
192
type Callback = (response: ImagePickerResponse) => any;
193
194
/** Media type selection */
195
type MediaType = 'photo' | 'video' | 'mixed';
196
197
/** Camera type selection */
198
type CameraType = 'back' | 'front';
199
200
/** Photo quality levels */
201
type PhotoQuality =
202
| 0 | 0.1 | 0.2 | 0.3 | 0.4 | 0.5
203
| 0.6 | 0.7 | 0.8 | 0.9 | 1;
204
205
/** Video quality options for Android */
206
type AndroidVideoOptions = 'low' | 'high';
207
208
/** Video quality options for iOS */
209
type iOSVideoOptions = 'low' | 'medium' | 'high';
210
211
/** Error codes for failed operations */
212
type ErrorCode = 'camera_unavailable' | 'permission' | 'others';
213
```
214
215
## Platform Support
216
217
| Feature | iOS | Android | Web |
218
|---------|-----|---------|-----|
219
| Photo capture/selection | ✅ | ✅ | ✅ |
220
| Video capture/selection | ✅ | ✅ | ❌ |
221
| Multiple selection | ✅ | ✅ | ✅ |
222
| Quality control | ✅ | ✅ | ❌ |
223
| Camera type selection | ✅ | ✅ | ❌ |
224
| Base64 encoding | ✅ | ✅ | ✅ |
225
| Save to photos | ✅ | ✅ | ❌ |
226
| MIME type restrictions | ❌ | ✅ | ❌ |
227
228
## Usage Examples
229
230
### Camera with Custom Options
231
232
```typescript
233
import { launchCamera, CameraOptions } from "react-native-image-picker";
234
235
const options: CameraOptions = {
236
mediaType: 'photo',
237
quality: 0.8,
238
maxWidth: 1000,
239
maxHeight: 1000,
240
cameraType: 'back',
241
saveToPhotos: true,
242
includeBase64: false,
243
};
244
245
try {
246
const result = await launchCamera(options);
247
248
if (result.didCancel) {
249
console.log('User cancelled camera');
250
} else if (result.errorMessage) {
251
console.error('Camera Error:', result.errorMessage);
252
} else if (result.assets && result.assets[0]) {
253
const asset = result.assets[0];
254
console.log('Captured image:', {
255
uri: asset.uri,
256
width: asset.width,
257
height: asset.height,
258
fileSize: asset.fileSize,
259
});
260
}
261
} catch (error) {
262
console.error('Camera launch failed:', error);
263
}
264
```
265
266
### Multiple Image Selection
267
268
```typescript
269
import { launchImageLibrary, ImageLibraryOptions } from "react-native-image-picker";
270
271
const options: ImageLibraryOptions = {
272
mediaType: 'photo',
273
selectionLimit: 5, // Allow up to 5 images
274
quality: 0.9,
275
includeBase64: false,
276
};
277
278
const result = await launchImageLibrary(options);
279
280
if (result.assets) {
281
console.log(`Selected ${result.assets.length} images:`);
282
result.assets.forEach((asset, index) => {
283
console.log(`Image ${index + 1}:`, {
284
uri: asset.uri,
285
fileName: asset.fileName,
286
fileSize: asset.fileSize,
287
type: asset.type,
288
});
289
});
290
}
291
```
292
293
### Video Recording
294
295
```typescript
296
import { launchCamera, CameraOptions } from "react-native-image-picker";
297
298
const videoOptions: CameraOptions = {
299
mediaType: 'video',
300
videoQuality: 'high',
301
durationLimit: 60, // 60 seconds max
302
cameraType: 'back',
303
};
304
305
const result = await launchCamera(videoOptions);
306
307
if (result.assets && result.assets[0]) {
308
const video = result.assets[0];
309
console.log('Recorded video:', {
310
uri: video.uri,
311
duration: video.duration,
312
fileSize: video.fileSize,
313
type: video.type,
314
});
315
}
316
```
317
318
### Callback Usage Pattern
319
320
```typescript
321
import { launchImageLibrary, ImagePickerResponse } from "react-native-image-picker";
322
323
// Using callback instead of await
324
launchImageLibrary(
325
{ mediaType: 'photo', selectionLimit: 1 },
326
(response: ImagePickerResponse) => {
327
if (response.assets && response.assets[0]) {
328
console.log('Selected image URI:', response.assets[0].uri);
329
}
330
}
331
);
332
```
333
334
## Error Handling
335
336
```typescript
337
import { launchCamera, ErrorCode } from "react-native-image-picker";
338
339
const result = await launchCamera({ mediaType: 'photo' });
340
341
if (result.errorCode) {
342
switch (result.errorCode) {
343
case 'camera_unavailable':
344
console.error('Camera not available on this device');
345
break;
346
case 'permission':
347
console.error('Camera permission denied');
348
break;
349
case 'others':
350
console.error('Other error:', result.errorMessage);
351
break;
352
}
353
}
354
```