Scan QR codes and barcodes from local image files in React Native (iOS Vision + Android ML Kit), with Expo prebuild support.
- Multi-barcode detection in a single image
- Mixed formats in one scan flow
- Auto preprocessing: grayscale, contrast boost, rotation retry (
0°–270°) - TypeScript support
- React Native
>=0.70.0(validated through0.79.x;0.80.x+compatibility is pending), React>=17.0.0, Node>=18 - iOS
13.4+, AndroidminSdkVersion 24+
Native module — works with Expo prebuild, not Expo Go.
npx expo install react-native-image-code-scanner
npx expo prebuild --clean
npx expo run:ios # or: npx expo run:androidyarn add react-native-image-code-scanner
cd ios && pod installIf your app picks images from the camera roll or camera, add to Info.plist:
<key>NSPhotoLibraryUsageDescription</key>
<string>This app needs access to photo library to select images for barcode scanning</string>
<key>NSCameraUsageDescription</key>
<string>This app needs camera access to scan barcodes</string>Works with image pickers that return a supported local path or URI:
- Android: local file paths,
file://URIs, and resolver-backedcontent://URIs. - iOS: local file paths and
file://URIs, including percent-encoded paths.
Schemes such as ph://, assets-library://, remote URLs, and other provider-specific values are not guaranteed to work.
import*asImagePickerfrom'expo-image-picker';importImageCodeScanner,{BarcodeFormat,}from'react-native-image-code-scanner';asyncfunctionpickAndScan(){constpicked=awaitImagePicker.launchImageLibraryAsync({mediaTypes: ImagePicker.MediaTypeOptions.Images,quality: 1,});if(picked.canceled||!picked.assets?.[0]?.uri)return[];constresults=awaitImageCodeScanner.scan({path: picked.assets[0].uri,formats: [BarcodeFormat.QR_CODE,BarcodeFormat.CODE_128],});// results is ScanResult[] — may contain 0, 1, or many barcodesreturnresults;}Also compatible with react-native-image-picker and other pickers when they return one of the supported values above.
ImageCodeScanner.scan(options: ScanOptions): Promise<ScanResult[]>interfaceScanOptions{path: string;formats?: BarcodeFormat[];// default: [QR_CODE]enhanceContrast?: boolean;// default: trueconvertToGrayscale?: boolean;// default: truetryRotations?: boolean;// default: true}interfaceScanResult{content: string;format: string;// no bounding-box coordinates}Multi-barcode:scan() returns all barcodes found in one image — no extra option needed. Preprocessing stops once at least one code is detected, but every code from that pass is returned.
Supported formats:QR_CODE, CODE_128, CODE_39, CODE_93, EAN_13, EAN_8, UPC_A, UPC_E, PDF_417, DATA_MATRIX, AZTEC, ITF, CODABAR
Preprocessing runs automatically by default: original → grayscale → contrast enhancement → rotation retries.
Set enhanceContrast, convertToGrayscale, or tryRotations to false to skip those retry passes.
- Resize very large images before scanning; pass only the
formatsyou need. - Process batch jobs sequentially to reduce memory spikes.
- Test on both iOS and Android for critical flows.
- No result: check image quality/resolution, limit
formats, crop closer to the barcode. - iOS build:
cd ios && pod install; deployment target13.4+. - Android build:
cd android && ./gradlew clean;minSdkVersion >= 24. - Expo: requires prebuild; not supported in Expo Go.
See example app and example README.
Run checks:
yarn typecheck yarn lint yarn test yarn buildCreate a release:
yarn release
This bumps the version and creates a
vX.Y.Ztag.Push the release commit and tag:
git push && git push --tags
GitHub Actions publishes to npm automatically after CI passes for the release tag.
Verify the published version:
npm view react-native-image-code-scanner versionFor a beta release:
yarn release:beta
git push && git push --tagsPlease read CONTRIBUTING.md.
MIT