This page documents the Barcode Scanning API in more detail than the README quick-start.
Barcode scanning is implemented by configured Nitro recognizers for both live frames and static images.
import { useFrameOutput } from 'react-native-vision-camera';
import {
useBarcodeScanning,
processImageBarcodeScanning,
type BarcodeScanningOptions,
type BarcodeScanningArguments,
type BarcodeScanningImageOptions,
type BarcodeScanningResult,
} from 'react-native-vision-camera-mlkit';Use useBarcodeScanning() for live camera frames, inside a useFrameOutput
onFrame worklet.
const { barcodeScanning } = useBarcodeScanning({
formats: ['QR_CODE', 'CODE_128'],
enableAllPotentialBarcodes: true,
scaleFactor: 1,
invertColors: false,
});
const frameOutput = useFrameOutput({
onFrame(frame) {
'worklet';
try {
const result = barcodeScanning(frame, {
outputOrientation: 'portrait',
});
console.log(result.barcodes);
} finally {
frame.dispose();
}
},
});formats?: BarcodeFormat[]enableAllPotentialBarcodes?: boolean(Android only)scaleFactor?: number(0.9-1.0)invertColors?: booleanroi?: RegionOfInterest(crop processing to a rectangle of the frame; see the Region of Interest section in the main README)frameProcessInterval?: number(deprecated compatibility field; v2 does not use it to throttle processing)
outputOrientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'(iOS only)
Use processImageBarcodeScanning(uri, options) for local images. Each call
creates a Nitro scanner with options and runs recognition asynchronously.
const result = await processImageBarcodeScanning(imageUri, {
formats: ['QR_CODE', 'PDF417'],
enableAllPotentialBarcodes: true,
orientation: 'portrait',
invertColors: false,
scaleFactor: 1,
});formats?: BarcodeFormat[]enableAllPotentialBarcodes?: boolean(Android only)orientation?: 'portrait' | 'portrait-upside-down' | 'landscape-left' | 'landscape-right'(overrides EXIF orientation; omit it to use image metadata)invertColors?: booleanscaleFactor?: number(0.9-1.0)roi?: RegionOfInterest(crop processing to a rectangle of the image; see the Region of Interest section in the main README)
Static images must be local and readable. iOS accepts an absolute path or a
file:// URI. Android also accepts content:// URIs, which are copied to a
temporary cache file. Remote URLs and platform-library schemes such as
ph:// are not supported. Static processing does not require Worklets or a
camera, but VisionCamera v5 and Nitro Modules remain native package
dependencies.
ALL_FORMATSQR_CODEAZTECPDF417DATA_MATRIXCODE_128CODE_39CODE_93CODABAREAN_13EAN_8ITFUPC_AUPC_EUNKNOWN
BarcodeScanningResult contains barcodes[].
Each barcode includes:
- geometry:
bounds,corners(optional — may be absent for potential barcodes) - identity:
format,formatName,valueType,valueTypeName—format/valueTypeare the raw ML Kit numeric codes; the*Namevariants are the human-readable string equivalents and are what you should match against in application code - raw payload:
rawValue,displayValue,rawBytes isPotential(true for potential/undecoded barcode candidates; whentrue,rawValue/rawBytesmay benull)- parsed payload:
value?: BarcodeParsedValue
BarcodeParsedValue is a discriminated union with type as TYPE_* values.
Examples:
TYPE_WIFITYPE_URLTYPE_CONTACT_INFOTYPE_CALENDAR_EVENTTYPE_DRIVER_LICENSETYPE_TEXTTYPE_PRODUCTTYPE_ISBN
Use switch (barcode.value?.type) for strong type inference in TypeScript.
Static Nitro calls reject invalid schemes, missing or unreadable files, and images the platform decoder cannot read. The package exports these compatibility error-message constants:
IMAGE_NOT_FOUND_ERRORINVALID_URI_ERRORIMAGE_PROCESSING_FAILED_ERRORUNSUPPORTED_IMAGE_FORMAT_ERROR
These constants are retained for source compatibility and user-facing fallback
messages. Nitro rejection messages are platform-specific and are not guaranteed
to equal these strings; do not branch on error.message.
- Filter
formatswhenever possible for better performance. - Always call
frame.dispose()exactly once for every frame, including frames you skip; keep disposal in afinallyblock around the whole callback. frameProcessIntervalhas no throttling effect in v2. Decide whether to call the scanner insideonFrame, while still disposing every frame.- Keep
scaleFactoras high as possible for decoding reliability.