A lightweight, high-performance React Native library for scanning QR codes and barcodes from images with automatic preprocessing for optimal recognition. Built with native performance in mind using iOS Vision Framework and Android ML Kit.
- π High Performance: Native implementation using iOS Vision Framework and Google ML Kit
- π± Cross-Platform: Support for both iOS and Android
- π― Multiple Formats: Supports 13+ barcode formats including QR, Code128, EAN, UPC, and more
- π§ Automatic Preprocessing: Built-in image enhancement automatically applied for better recognition
- β‘ New Architecture Ready: Full support for React Native's New Architecture (Turbo Modules)
- π¦ Lightweight: Minimal dependencies, optimized bundle size
- π Smart Recognition: Automatic rotation, grayscale conversion, and contrast enhancement
- π Type Safe: Full TypeScript support with comprehensive type definitions
- π οΈ Expo Compatible: Works with Expo (requires prebuild for native functionality)
- ποΈ Robust CI/CD: Enhanced build pipeline with improved cross-platform reliability
| Format | iOS | Android |
|---|---|---|
| QR Code | β | β |
| Code 128 | β | β |
| Code 39 | β | β |
| Code 93 | β | β |
| EAN-13 | β | β |
| EAN-8 | β | β |
| UPC-A | β | β |
| UPC-E | β | β |
| PDF417 | β | β |
| Data Matrix | β | β |
| Aztec | β | β |
| ITF | β | β |
| Codabar | β | β |
| React Native | Package Version | Architecture Support | Status |
|---|---|---|---|
| 0.70.x - 0.74.x | β 1.0.x | Old Architecture | Fully Supported |
| 0.75.x - 0.78.x | β 1.0.x | Old & New Architecture | Fully Supported |
| 0.79.x | β 1.0.x | New Architecture (default) | Latest - Full Support |
| 0.80.x+ | π 1.0.x | New Architecture | Ready when released |
- React Native: >=0.70.0
- React: >=17.0.0
- iOS: 13.4+
- Android: minSdkVersion 21+
- Node: >=18
npm install react-native-image-code-scanner
# or
yarn add react-native-image-code-scannercd ios && pod installRequirements:
- iOS 13.4+
- Add camera usage description to
Info.plistif you're picking images from camera:
<key>NSCameraUsageDescription</key>
<string>This app needs access to camera to scan barcodes</string>No additional setup required for Android. The library automatically includes ML Kit dependencies.
Requirements:
- minSdkVersion 21+
- compileSdkVersion 33+
For Expo projects, you'll need to prebuild your project to use native modules:
# Install the library
npm install react-native-image-code-scanner
#or
npx expo install react-native-image-code-scanner
# Prebuild your project
npx expo prebuild --clean
# Run on your preferred platform
npx expo run:ios
# or
npx expo run:androidNote: This library requires prebuild because it uses native iOS Vision Framework and Android ML Kit. It won't work in Expo Go.
import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner';
// Scan QR code from image
const scanQRCode = async (imagePath: string) => {
try {
const results: ScanResult[] = await ImageCodeScanner.scan({
path: imagePath,
});
if (results.length > 0) {
const firstResult = results[0];
console.log('QR Code found:', firstResult.content);
console.log('Format:', firstResult.format); // "QR_CODE"
} else {
console.log('No QR code found in image');
}
} catch (error) {
console.error('Scan error:', error);
}
};import ImageCodeScanner, {
BarcodeFormat,
ScanResult,
} from 'react-native-image-code-scanner';
const scanMultipleFormats = async (imagePath: string) => {
try {
const results: ScanResult[] = await ImageCodeScanner.scan({
path: imagePath,
formats: [
BarcodeFormat.QR_CODE,
BarcodeFormat.CODE_128,
BarcodeFormat.EAN_13,
],
// Automatic preprocessing is enabled by default for optimal recognition
});
results.forEach((result, index) => {
console.log(`Barcode ${index + 1}:`, result.content);
console.log(`Format:`, result.format);
});
} catch (error) {
console.error('Scan error:', error);
}
};The scanner automatically applies multiple preprocessing techniques to maximize recognition:
- Original Image: First scan attempt
- Grayscale Conversion: Improves detection in colored backgrounds
- Contrast Enhancement: Better recognition in low-contrast images
- Rotation Attempts: Tries 0Β°, 90Β°, 180Β°, and 270Β° rotations
As soon as a barcode is detected with any technique, the result is returned immediately for optimal performance.
import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner';
import { launchImageLibrary } from 'react-native-image-picker';
const scanFromGallery = async () => {
const result = await launchImageLibrary({
mediaType: 'photo',
selectionLimit: 1,
});
if (result.assets && result.assets[0]) {
const imagePath = result.assets[0].uri;
const scanResults: ScanResult[] = await ImageCodeScanner.scan({
path: imagePath,
formats: [ImageCodeScanner.BarcodeFormat.QR_CODE],
// Automatic preprocessing is enabled by default
});
if (scanResults.length > 0) {
scanResults.forEach((result) => {
console.log('Content:', result.content);
console.log('Format:', result.format);
});
}
}
};import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner';
import * as ImagePicker from 'expo-image-picker';
const scanFromGallery = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 1,
});
if (!result.canceled && result.assets && result.assets[0]) {
const imagePath = result.assets[0].uri;
const scanResults: ScanResult[] = await ImageCodeScanner.scan({
path: imagePath,
formats: [ImageCodeScanner.BarcodeFormat.QR_CODE],
// Automatic preprocessing is enabled by default
});
if (scanResults.length > 0) {
scanResults.forEach((result) => {
console.log('Content:', result.content);
console.log('Format:', result.format);
});
}
}
};import ImageCodeScanner, {
BarcodeFormat,
ScanResult,
} from 'react-native-image-code-scanner';
// Scan with automatic preprocessing and multiple formats
const scanEverything = async (imagePath: string): Promise<ScanResult[]> => {
try {
const results: ScanResult[] = await ImageCodeScanner.scan({
path: imagePath,
formats: Object.values(BarcodeFormat), // All supported formats
// Automatic preprocessing is enabled by default
});
console.log(`Found ${results.length} barcodes:`);
results.forEach((result, index) => {
console.log(`${index + 1}. ${result.format}: ${result.content}`);
});
return results;
} catch (error) {
console.error('Scan failed:', error);
return [];
}
};Scans an image for barcodes with automatic preprocessing enabled.
| Parameter | Type | Required | Description |
|---|---|---|---|
options |
ScanOptions |
Yes | Scanning configuration |
interface ScanOptions {
path: string; // Path to the image file
formats?: BarcodeFormat[]; // Array of barcode formats to detect (default: QR_CODE)
}Promise<ScanResult[]> - Array of scan results with content and format information
interface ScanResult {
content: string; // The decoded barcode content
format: string; // The detected barcode format (e.g., "QR_CODE", "EAN_13")
}Enum of supported barcode formats:
enum BarcodeFormat {
QR_CODE = 'QR_CODE',
CODE_128 = 'CODE_128',
CODE_39 = 'CODE_39',
CODE_93 = 'CODE_93',
EAN_13 = 'EAN_13',
EAN_8 = 'EAN_8',
UPC_A = 'UPC_A',
UPC_E = 'UPC_E',
PDF_417 = 'PDF_417',
DATA_MATRIX = 'DATA_MATRIX',
AZTEC = 'AZTEC',
ITF = 'ITF',
CODABAR = 'CODABAR',
}The library automatically applies the following preprocessing techniques for better recognition:
- Grayscale Conversion: Converts images to grayscale for improved barcode detection
- Contrast Enhancement: Enhances image contrast to make barcodes more readable
- Rotation Detection: Tries multiple orientations (0Β°, 90Β°, 180Β°, 270Β°) automatically
- Smart Retry Logic: If initial scan fails, automatically tries with different preprocessing techniques
-
πΌοΈ Image Size: Large images may take longer to process. Consider resizing images before scanning if performance is critical.
-
π― Format Selection: Specify only the formats you need rather than scanning for all formats.
-
π§ Preprocessing: Automatic preprocessing improves recognition rates but may increase processing time. The library optimizes this automatically.
-
π± Platform Differences: iOS Vision Framework and Android ML Kit may have slight differences in recognition capabilities. Test on both platforms for critical use cases.
-
π Batch Processing: For multiple images, process them sequentially rather than in parallel to avoid memory issues.
- Ensure the image has sufficient quality and resolution
- Specify only the relevant barcode formats to reduce noise
- Check that the barcode format is supported and included in the formats array
- Try resizing/cropping the image (e.g., focus on the barcode area) or improving contrast before scanning
- Clean build folder:
cd ios && rm -rf build && pod install - Ensure minimum iOS version is 13.4 or higher in your Podfile
- Check that all pods are properly installed
- Ensure you have the correct Kotlin version in your project
- Clean and rebuild:
cd android && ./gradlew clean - Check that ML Kit dependencies are properly included
- Prebuild Required: This library requires prebuild because it uses native modules
- Expo Go Limitation: Won't work in Expo Go - use prebuild for full functionality
- Build Errors: Run
npx expo prebuild --cleanto start fresh
Check out the example app for a complete implementation with Expo:
cd example
npm install
# or
yarn install
# For quick UI testing (Expo Go)
npm start
# For full functionality (requires prebuild)
npm run prebuild
npm run build:ios # or npm run build:androidThe example app demonstrates:
- Image selection from camera and gallery using Expo Image Picker
- Automatic preprocessing (always on; no manual toggles required)
- Multiple barcode format selection
- Performance timing measurements
- Beautiful, responsive UI
- Cross-platform support (iOS, Android, Web)
Important Notes:
- π Expo Go Mode: Barcode scanning won't work
- β‘ Prebuild Mode: Full functionality including barcode scanning (requires Xcode/Android Studio)
- π See README.md for detailed setup instructions
Platform Support:
- π± iOS: Gallery access
- π€ Android: Gallery access
We welcome contributions! Please see our Contributing Guide for details.
- Clone the repository
- Install dependencies:
yarn install - Run tests:
yarn test - Run linter:
yarn lint - Run type checking:
yarn typecheck
MIT
- π Report Issues
- π¬ Discussions
- β Star us on GitHub