These five packages handle camera access, image picking, and barcode scanning in React Native apps, but they serve different purposes and vary significantly in maintenance status. react-native-camera was the original camera library but is now deprecated. react-native-vision-camera is its modern successor with better performance and features. react-native-camera-kit offers a simplified camera API with built-in UI components. react-native-image-picker focuses on selecting images from the gallery or capturing photos through system dialogs. react-native-qrcode-scanner provides QR code scanning functionality but depends on the deprecated react-native-camera. Understanding their differences helps you choose the right tool for your specific needs.
Building camera features in React Native requires careful package selection. The ecosystem has evolved significantly, with some libraries deprecated and others offering modern alternatives. Let's compare these five packages across real-world scenarios.
react-native-camera was the original camera library for React Native. It provided direct camera access with custom UI controls. However, it's now deprecated and archived β the repository is read-only and no longer maintained.
// react-native-camera (DEPRECATED - DO NOT USE IN NEW PROJECTS)
import { RNCamera } from 'react-native-camera';
function CameraScreen() {
return (
<RNCamera
style={{ flex: 1 }}
type={RNCamera.Constants.Type.back}
onBarCodeRead={(result) => console.log(result.data)}
>
<TouchableOpacity onPress={takePicture}>
<Text>Capture</Text>
</TouchableOpacity>
</RNCamera>
);
}
react-native-vision-camera is the official successor. It's built on CameraX (Android) and AVFoundation (iOS), offering better performance and frame processing capabilities.
// react-native-vision-camera (RECOMMENDED)
import { Camera, useCameraDevice } from 'react-native-vision-camera';
function CameraScreen() {
const device = useCameraDevice('back');
return (
<Camera
style={{ flex: 1 }}
device={device}
isActive={true}
photo={true}
onFrameProcessor={(frame) => processFrame(frame)}
/>
);
}
react-native-camera-kit provides camera access with built-in UI components and a simpler API. It handles more of the UI work for you.
// react-native-camera-kit
import { CameraScreen } from 'react-native-camera-kit';
function CameraScreen() {
return (
<CameraScreen
scanBarcode={true}
onReadCode={(event) => console.log(event.nativeEvent.codeStringValue)}
showFrame={true}
/>
);
}
react-native-image-picker doesn't provide a custom camera UI. Instead, it opens native system dialogs for image selection or quick photo capture.
// react-native-image-picker
import { launchCamera, launchImageLibrary } from 'react-native-image-picker';
async function pickImage() {
// Open camera
const cameraResult = await launchCamera({ mediaType: 'photo' });
// Or open gallery
const galleryResult = await launchImageLibrary({ mediaType: 'photo' });
if (cameraResult.assets) {
console.log(cameraResult.assets[0].uri);
}
}
react-native-qrcode-scanner focuses specifically on QR code scanning but depends on the deprecated react-native-camera.
// react-native-qrcode-scanner (DEPENDS ON DEPRECATED PACKAGE)
import QRCodeScanner from 'react-native-qrcode-scanner';
function ScannerScreen() {
return (
<QRCodeScanner
onRead={(e) => console.log(e.data)}
flashMode={QRCodeScanner.Constants.FlashMode.auto}
/>
);
}
| Package | Custom UI Support | Notes |
|---|---|---|
react-native-camera | β Yes | Deprecated |
react-native-vision-camera | β Yes | Full control, modern API |
react-native-camera-kit | β Yes | Built-in UI components |
react-native-image-picker | β No | System dialogs only |
react-native-qrcode-scanner | β οΈ Limited | Basic scanner UI only |
react-native-vision-camera gives you complete control over the camera preview and overlays:
// Full custom UI with vision-camera
function CustomCamera() {
const camera = useRef(null);
return (
<View style={{ flex: 1 }}>
<Camera
ref={camera}
device={device}
isActive={true}
style={{ flex: 1 }}
/>
<View style={{ position: 'absolute', bottom: 50 }}>
<Button title="Capture" onPress={takePhoto} />
<Button title="Switch Camera" onPress={toggleCamera} />
</View>
</View>
);
}
react-native-image-picker has no custom UI β you get system dialogs:
// No custom UI possible with image-picker
async function capturePhoto() {
const result = await launchCamera({
mediaType: 'photo',
cameraType: 'back',
saveToPhotos: true
});
// That's it β no custom overlays or controls
}
| Package | Built-in Scanning | Performance | Notes |
|---|---|---|---|
react-native-camera | β Yes | Good | Deprecated |
react-native-vision-camera | β Yes | Excellent | Via code scanner frame |
react-native-camera-kit | β Yes | Good | Built-in prop |
react-native-image-picker | β No | N/A | Not supported |
react-native-qrcode-scanner | β Yes | Good | QR only, deprecated dependency |
react-native-vision-camera uses frame processors for scanning:
// vision-camera with code scanner
import { useCodeScanner } from 'react-native-vision-camera';
function Scanner() {
const codeScanner = useCodeScanner({
codeTypes: ['qr', 'ean-13'],
onCodeScanned: (codes) => {
console.log(`Scanned ${codes.length} codes!`);
}
});
return (
<Camera
device={device}
isActive={true}
codeScanner={codeScanner}
style={{ flex: 1 }}
/>
);
}
react-native-qrcode-scanner is QR-specific:
// qrcode-scanner (QR only)
function QRScanner() {
return (
<QRCodeScanner
onRead={(e) => Linking.openURL(e.data)}
topContent={<Text>Scan QR Code</Text>}
bottomContent={<Text>Point at QR code</Text>}
/>
);
}
| Package | Video Support | Quality Control | Notes |
|---|---|---|---|
react-native-camera | β Yes | Basic | Deprecated |
react-native-vision-camera | β Yes | Advanced | 4K, FPS control |
react-native-camera-kit | β Yes | Basic | Simple API |
react-native-image-picker | β Yes | Limited | Via system dialog |
react-native-qrcode-scanner | β No | N/A | Not supported |
react-native-vision-camera offers advanced video controls:
// Advanced video recording with vision-camera
async function recordVideo() {
if (camera.current) {
const video = await camera.current.startRecording({
onRecordingFinished: (video) => console.log(video.path),
onRecordingError: (error) => console.error(error),
videoCodec: 'h264',
videoBitrate: 10000000
});
}
}
react-native-image-picker video is limited to system capabilities:
// Basic video via system dialog
async function recordVideo() {
const result = await launchCamera({
mediaType: 'video',
videoQuality: 'high',
durationLimit: 30
});
// Limited to what the system dialog offers
}
| Package | Frame Access | Performance | Use Cases |
|---|---|---|---|
react-native-camera | β οΈ Limited | Poor | Legacy only |
react-native-vision-camera | β Yes | Excellent | ML, filters, analysis |
react-native-camera-kit | β No | N/A | Not supported |
react-native-image-picker | β No | N/A | Not supported |
react-native-qrcode-scanner | β No | N/A | Not supported |
react-native-vision-camera is the only modern option for frame processing:
// Real-time frame processing
function FrameProcessorCamera() {
const frameProcessor = useFrameProcessor((frame) => {
'worklet';
// Access frame data for ML or filters
const imageData = frame.toRGBArray();
// Process with vision-js or custom logic
}, []);
return (
<Camera
device={device}
isActive={true}
frameProcessor={frameProcessor}
pixelFormat="rgb"
style={{ flex: 1 }}
/>
);
}
This is critical for architectural decisions:
| Package | Status | Recommendation |
|---|---|---|
react-native-camera | β Deprecated/Archived | DO NOT USE |
react-native-vision-camera | β Active | RECOMMENDED |
react-native-camera-kit | β Active | Consider for simple needs |
react-native-image-picker | β Active | RECOMMENDED for image picking |
react-native-qrcode-scanner | β οΈ Deprecated Dependency | AVOID (use vision-camera instead) |
react-native-camera repository message:
"This repository has been archived. Please migrate to react-native-vision-camera."
react-native-qrcode-scanner inherits this problem since it depends on react-native-camera internally. For QR scanning in new projects, use vision-camera's useCodeScanner hook instead.
You need users to upload a profile photo β either from gallery or quick camera capture.
β
Best choice: react-native-image-picker
// Simple and effective for this use case
import { launchImageLibrary } from 'react-native-image-picker';
async function uploadProfilePicture() {
const result = await launchImageLibrary({
mediaType: 'photo',
selectionLimit: 1,
maxWidth: 512,
maxHeight: 512
});
if (result.assets) {
await uploadToServer(result.assets[0].uri);
}
}
Why? No need for custom camera UI. System dialogs are familiar to users and require minimal code.
You're building an app that scans documents with edge detection and perspective correction.
β
Best choice: react-native-vision-camera
// Full control for document scanning
function DocumentScanner() {
const frameProcessor = useFrameProcessor((frame) => {
'worklet';
// Run edge detection algorithm
const edges = detectDocumentEdges(frame);
// Apply perspective correction
}, []);
return (
<Camera
device={device}
isActive={true}
frameProcessor={frameProcessor}
photo={true}
/>
);
}
Why? You need frame access for image processing. Only vision-camera provides this with good performance.
Your app needs to scan QR codes for payments with high reliability.
β
Best choice: react-native-vision-camera (NOT qrcode-scanner)
// Modern QR scanning
function PaymentScanner() {
const codeScanner = useCodeScanner({
codeTypes: ['qr'],
onCodeScanned: async (codes) => {
const paymentData = parsePaymentQR(codes[0].value);
await processPayment(paymentData);
}
});
return (
<Camera
device={device}
isActive={true}
codeScanner={codeScanner}
style={{ flex: 1 }}
/>
);
}
Why? react-native-qrcode-scanner depends on deprecated code. Vision-camera offers better performance and active maintenance.
You're building a camera with real-time filters, stickers, and effects.
β
Best choice: react-native-vision-camera
// Real-time filters with frame processing
function FilterCamera() {
const frameProcessor = useFrameProcessor((frame) => {
'worklet';
// Apply filter using vision-js
applySepiaFilter(frame);
// Add overlay stickers
renderStickers(frame);
}, []);
return (
<Camera
device={device}
isActive={true}
frameProcessor={frameProcessor}
pixelFormat="rgb"
/>
);
}
Why? Frame processing is essential. Vision-camera is the only actively maintained option with this capability.
You need a camera screen quickly with minimal customization.
β
Best choice: react-native-camera-kit
// Quick setup with built-in UI
function QuickCamera() {
return (
<CameraScreen
scanBarcode={true}
onReadCode={(event) => handleScan(event)}
flashMode="auto"
cameraType="back"
/>
);
}
Why? Less code, built-in UI components work out of the box. Good for MVPs or simple use cases.
| Feature | react-native-camera | react-native-vision-camera | react-native-camera-kit | react-native-image-picker | react-native-qrcode-scanner |
|---|---|---|---|---|---|
| Status | β Deprecated | β Active | β Active | β Active | β οΈ Deprecated Dependency |
| Custom UI | β | β | β | β | β οΈ Limited |
| QR/Barcode | β | β | β | β | β (QR only) |
| Video Recording | β | β (Advanced) | β | β (Basic) | β |
| Frame Processing | β οΈ Poor | β Excellent | β | β | β |
| Performance | Poor | Excellent | Good | Good | Good |
| New Projects | β Avoid | β Recommended | β Consider | β Recommended | β Avoid |
For new projects:
react-native-vision-camerareact-native-image-pickerreact-native-camera-kitAvoid for new projects:
react-native-camera β Deprecated and archivedreact-native-qrcode-scanner β Depends on deprecated packageMigration path:
If you're using react-native-camera or react-native-qrcode-scanner, plan to migrate to react-native-vision-camera. The API is different but offers better performance and long-term support.
// Migration example: react-native-camera β vision-camera
// OLD (react-native-camera)
<RNCamera onBarCodeRead={handleScan} />
// NEW (react-native-vision-camera)
const codeScanner = useCodeScanner({ onCodeScanned: handleScan });
<Camera codeScanner={codeScanner} />
react-native-vision-camera is the modern standard for custom camera implementationsreact-native-image-picker remains the best choice for simple image selectionuseCodeScanner, not qrcode-scannerChoose based on your specific needs, but always prioritize actively maintained packages for production applications.
Avoid this package for new projects β it has been officially deprecated and archived. The maintainers recommend migrating to react-native-vision-camera instead. Only consider this if you're maintaining legacy code that already depends on it and migration isn't feasible yet.
Choose react-native-camera-kit if you need a camera implementation with built-in UI components and a simpler API surface. It works well for apps that need standard camera functionality without complex frame processing. Best for teams that want less configuration overhead compared to vision-camera.
Choose react-native-image-picker when you only need to let users select existing images from their gallery or take quick photos through system dialogs. It doesn't provide a custom camera UI, but it's perfect for profile pictures, image uploads, or any scenario where native picker dialogs are acceptable.
Avoid this for new projects since it depends on the deprecated react-native-camera. For QR scanning in new apps, use react-native-vision-camera with its built-in barcode scanning frames or consider expo-barcode-scanner if you're using Expo. Only use this for legacy maintenance.
Choose react-native-vision-camera for new projects requiring custom camera UI, video recording, frame processing, or barcode scanning. It offers the best performance, active maintenance, and modern APIs built on CameraX and AVFoundation. Ideal for apps needing advanced camera features like real-time filters or machine learning integration.
See this issue
We are looking for maintainers for this package, or to depreciate this in favor of react-native-vision-camera or expo-camera, if nobody want to maintain this package.
Follow our docs here https://react-native-camera.github.io/react-native-camera/
If you use this library on your commercial/personal projects, you can help us by funding the work on specific issues that you choose by using IssueHunt.io!
This gives you the power to prioritize our work and support the project contributors. Moreover it'll guarantee the project will be updated and maintained in the long run.
Available as part of the Tidelift Subscription
The maintainers of react-native-camera and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. Learn more.
You can also fund this project using open collective
Support us with a monthly donation and help us continue our activities. [Become a backer]
Become a sponsor and get your logo on our README on Github with a link to your site. [Become a sponsor]
The comprehensive camera module for React Native.
Supports:
import { RNCamera, FaceDetector } from 'react-native-camera';
We recommend using the releases from npm, however if you need some features that are not published on npm yet you can install react-native-camera from git.
yarn: yarn add react-native-camera@git+https://git@github.com/react-native-community/react-native-camera.git
npm: npm install --save react-native-camera@git+https://git@github.com/react-native-community/react-native-camera.git
To use the camera,
<uses-permission android:name="android.permission.CAMERA" />
To enable video recording feature you have to add the following code to the AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

...
<key>NSCameraUsageDescription</key>
<string>Your own description of the purpose</string>
...
For more information on installation, please refer to installation requirements.
For general introduction, please take a look into this RNCamera.
To report a security vulnerability, please use the
Tidelift will coordinate the fix and disclosure.