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 camera, add to Info.plist:
<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 * as ImagePicker from 'expo-image-picker';
import ImageCodeScanner, {
BarcodeFormat,
} from 'react-native-image-code-scanner';
async function pickAndScan() {
const picked = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
quality: 1,
});
if (picked.canceled || !picked.assets?.[0]?.uri) return [];
const results = await ImageCodeScanner.scan({
path: picked.assets[0].uri,
formats: [BarcodeFormat.QR_CODE, BarcodeFormat.CODE_128],
});
// results is ScanResult[] — may contain 0, 1, or many barcodes
return results;
}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[]>
interface ScanOptions {
path: string;
formats?: BarcodeFormat[]; // default: [QR_CODE]
enhanceContrast?: boolean; // default: true
convertToGrayscale?: boolean; // default: true
tryRotations?: boolean; // default: true
}
interface ScanResult {
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 build -
Create 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