Scanbot SDK has been acquired by Apryse! Learn more

Learn more
Skip to content

Choosing a React Native barcode scanner: react-native-vision-camera vs. expo-camera

Maya October 10, 2025 11 mins read
react-native-vision-camera vs. expo-camera

Open-source libraries provide developers with accessible tools to accelerate their work. Barcode scanning software is no exception. In this article, we will look at two established React Native barcode scanner libraries: react-native-vision-camera and expo-camera.  

Before we jump into the details, let’s start with a short summary:  

💡 Key findings

Supported platforms:

Supported barcode types:

  • react-native-vision-camera: Most common 1D & 2D barcodes, including GS1 DataBar and its variations
  • expo-camera: Same coverage, except support for GS1 DataBar

Capabilities:

Both libraries support multi-code scanning, omnidirectional decoding, camera switching, and torch toggling.

  • react-native-vision-camera: Feature parity across platforms
  • expo-camera: Several features exclusive to iOS

Maintenance and updates:

Both libraries are actively maintained and under development.

  • react-native-vision-camera: Frequent bug fixes, system updates and new features
  • expo-camera: Maintained within the Expo SDK, with three releases per year

Community support and developer resources:

Both libraries provide extensive documentation and guides.

  • react-native-vision-camera: Active community on GitHub, Stack Overflow and Reddit
  • expo-camera: Support via Expo’s GitHub and Discord, longer response times on issues

Limitations:

  • react-native-vision-camera
    • Unreliable performance on reflective surfaces
    • Occasional incorrect decoding of EAN-13, EAN-8 and Code 128
    • QR Code scanning issues on Android devices
  • expo-camera
    • Unreliable performance on curved surfaces
    • Photo latency on some Android devices
    • Web failures in SDK51+

Platform support

react-native-vision-camera (VisionCamera) provides a <Camera /> component, which enables barcode scanning through a configurable CodeScanner. It is available for Android API 21+ and iOS 12+.

expo-camera integrates barcode scanning through CameraView. It works on Android, iOS and Web. It relies on the following native libraries:  

Supported barcodes

Both packages support the most common barcode types. This excludes more niche symbologies like Micro QR Code, Micro PDF417, MSI Plessey, or MaxiCode.  

The react-native-vision-camera documentation mentions that the Android version supports ITF barcodes only from a minimum length of 6 characters – a limitation inherited from ML Kit.  

On iOS, the library has no official support for UPC-A barcodes. While the scanner can read them, it will return them as EAN-13.  You can convert the EAN-13 codes to UPC-A by manually removing the front 0 digit.  

Meanwhile, expo-camera notably does not support GS1 DataBar codes in any of the symbology’s variations. 

Barcode typesVision Camera – AndroidVision Camera – iOSexpo-camera – Androidexpo-camera – iOSexpo-camera – Web
UPC-A⚠️ 
UPC-E
EAN-8
EAN-13
ITF (Interleaved 2 of 5)
Code 39
Code 93
Code 128
Codabar
MSI Plessey
GS1 DataBar
GS1 DataBar Expanded
GS1 DataBar Limited
GS1 DataBar Stacked
QR Code
Micro QR Code
Data Matrix
Aztec
PDF417
Micro PDF417
MaxiCode

Legend: ✅ Supported ❌ Not supported ⚠️ Limited

Capabilities

Both libraries support a number of core features on all platforms, like scanning multiple codes, omnidirectional scanning, camera switching, and torch toggling.  

react-native-vision-camera additionally has autofocus, pinch-to-zoom, and scanning from images working consistently across platforms. User guidance and AR overlays are not provided by default but can be built via UI overlays and frame processors.  

expo-camera only supports these features on iOS. It’s also worth mentioning that on iOS it can only scan QR codes from images. Nevertheless, the library offers user guidance and highlighting overlays out of the box on iOS.  

FeatureVision Camera – AndroidVision Camera – iOSexpo-camera – Androidexpo-camera – iOSexpo-camera – Web
Scan multiple codes at once✅ 
Scan from images⚠️ Only QR
Omnidirectional scanning
Camera switching
Torch toggle
Autofocus
Pinch-to-zoom
Define ROI
User guidance⚠️⚠️
AR overlay⚠️⚠️

Legend: ✅ Supported ❌ Not supported ⚠️ Limited

Customizability

react-native-vision-camera is highly flexible, as the library is deliberately low-level. It only gives you the Camera component (a native preview surface) plus APIs to capture photos, record video, and run frame processors. Developers must therefore implement all UI controls manually in React Native.  

Because expo-camera is part of the Expo SDK, its options are more constrained, but simpler. Developers still have to build their own capture button, flash toggle, or scanning overlay. That said, Expo’s docs include example implementations of a basic camera screen (with buttons) that you can copy and adapt. 

In terms of ease of implementation, the difference is that Expo’s docs give you more boilerplate examples to get started quickly, while VisionCamera leaves more up to you (but is more customizable). 

Maintenance and updates

Both libraries are actively maintained and under development.  

react-native-vision-camera has frequent updates including bug fixes and feature releases. Updates are also pushed after changes in React Native or the native operating systems.  

expo-camera is part of the Expo SDK, so its updates follow the broader SDK’s release cycle – roughly three times a year. It’s actively maintained, but its development pace is tied to Expo’s overall cadence rather than its own schedule.  

Community support and developer resources 

Both libraries have an engaged community, and dedicated documentation. 

The react-native-vision-camera GitHub repository is active and shows frequent pull requests. Maintainers of the project have set up a bot that automatically replies to new issues. Responses are generally fast.  

expo-camera is backed by the Expo ecosystem, which offers an official Discord channel where developers can ask questions. On GitHub, issues related to barcode scanning might take longer to resolve or get lower priority. As indicated previously, bug fixes may require waiting for an SDK update.  

See the table below to navigate to relevant developer resources.  

react-native-vision-cameraexpo-camera
Documentation 
GitHub repository 
npm package 
Integration tutorial 
Documentation 
GitHub repository 
npm package 

Limitations 

react-native-vision-camera 

Issues with reflective surfaces 

Scanning performance is reduced on reflective or wet packaging. In these conditions, barcodes may take significantly longer to decode or fail to be recognized. This results in user frustration. 

Misinterpreted barcode data 

On both Android and iOS, scans may return incorrect values. The issue occurs in version 4.5.2 with the supported types EAN-13, EAN-8, and Code 128, and exists even when limiting the enabled symbologies to these three. Attempts to mitigate – by aggregating scans and returning only the most-repeated result – introduce latency. 

QR code detection limited to top-right corner 

On some Android devices (e.g., Samsung A23, Realme C67), QR codes are only recognized when positioned in the top-right area of the frame. In other regions, detection fails, though the same codes are read correctly by the native camera app and on other devices (e.g., Samsung S21). 

On the Samsung A23, you can work around the issue by passing photo={true}. However, it only works for this specific device. On iOS devices, passing this parameter results in black or frozen frames.  

expo-camera 

Issues with curved surfaces 

On iOS, expo-camera may fail to reliably scan barcodes unless they are held perfectly centered and without rotation. This affects barcodes on both flat wrappers and round containers. 

Photo capture latency 

Photo capture performance is reduced on Android (Moto G8). In such conditions, images may take ~4 seconds to return after capture, even when lowering quality or enabling skipProcessing

Scanning failure on Web 

On Chrome and Firefox, the camera view renders correctly but no barcodes are detected. The problem appears in SDK 51+, where prop name changes introduced incompatibilities.  

While iOS and Android builds scan reliably across formats, Web builds in Chrome and Firefox only recognize QR codes at best, with other symbologies failing altogether. Some developers note that reverting to SDK 50 restores broader functionality, but newer versions leave Web scanning on desktop browsers incomplete and inconsistent. 

And the winner is…?  

Generally, react-native-vision-camera is the recommended option.

It benefits from frequent updates and an active community, making it the stronger choice if you want flexibility, quick bug fixes, or are building a more customized scanning experience.

expo-camera works well for teams already in the Expo ecosystem who value quick setup and minimal configuration, but it comes with trade-offs concerning feature set and platform reliability, especially on Web.

Scanbot SDK: Reliable and fast barcode scanning for React Native

Open-source libraries are useful but often come with limitations. Their reliance on native implementations can lead to inconsistent performance and incomplete barcode support, and long-term maintenance is not always guaranteed. 

The Scanbot Barcode Scanner SDK offers a commercial alternative with superior speed and reliability. Scans complete in as little as 0.04 seconds. Its advanced features include AR overlays, user guidance, and configurable regions of interest. The SDK also runs entirely offline, ensuring uninterrupted workflows even without connectivity. 

It includes ready-to-use UI components for quick integration, and a flat annual license covers unlimited scans on unlimited devices. Setup is straightforward, and the support team responds quickly. 

“The technical quality exceeded our expectations. Once we made the decision to go with Scanbot SDK, there were zero difficulties. Every support request got a quick response and an effective solution. The implementation was seamless.” (Indrek Ott, CEO @ Datanor) 

Are you interested in testing our scanner? Try our demo app or request a free 7-day trial license to integrate our React Native Barcode Scanner SDK in your project. 

Integrating the Scanbot React Native Barcode Scanner SDK 

After you’ve created your Expo project and added the iOS and Android platforms, install the React Native Barcode Scanner SDK using the following command:

npx expo install react-native-scanbot-barcode-scanner-sdk

To configure the plugin, add the following to your app.json file:

"plugins": [
  "expo-router",
  [
    "react-native-scanbot-barcode-scanner-sdk",
    {
      "iOSCameraUsageDescription": "Camera permission is needed to scan barcodes",
      "androidCameraPermission": true,
      "androidCameraFeature": true,
      "mavenURLs": true
    }
  ]
],

Then run:

npx expo prebuild

Alternatively, you can also apply the changes to the native projects manually.

Before using any feature of the React Native Barcode Scanner SDK, you need to initialize it. Ideally, initialization should be done as soon as the app is launched.

There are many ways to initialize the SDK that depend on your use case. In this example, we’re going to initialize the SDK inside a useEffect in _layout.tsx.

ScanbotBarcodeSDK
  .initializeSdk({ licenseKey: "" })
  .then(result => console.log(result))
  .catch(err => console.log(err));

The SDK’s RTU UI components make it easy to deploy different scanning modes in your app. In this example, we’re going to implement the simplest use case: single-barcode scanning.

In app/index.tsx, add a button that will start the scanning process.

<Button title={"Start single barcode scanning"} onPress={onSingleBarcodeScan} />

Now define onBarcodeScannerPress, which will start the single-barcode scanning mode:

const onSingleBarcodeScan = useCallback(async () => {
  try {
    /** Check license status and return early if the license is not valid */
    if (!(await ScanbotBarcodeSDK.getLicenseInfo()).data?.isLicenseValid) {
      return;
    }
    /**
     * Instantiate a configuration object of BarcodeScannerConfiguration and
     * start the barcode scanner with the configuration
     */
    const config = new BarcodeScannerConfiguration();
    /** Initialize the use case for single scanning */
    config.useCase = new SingleScanningMode();
    /** Start the BarcodeScanner */
    const result = await startBarcodeScanner(config);
    /** Handle the result if result status is OK */
    if (result.status === 'OK' && result.data) {
      Alert.alert(
        "Barcode Scanning successfully!",
        `${result.data.items.map(barcode =>
          `Barcode value: ${barcode.text} and type: ${barcode.type}`
        ).join("\n")}`);
    } else {
      console.log("The user has canceled the Barcode Scanning")
    }
  } catch (e: any) {
    console.log("An error has occurred while running Barcode Scanner", e.message);
  }
}, []);

To run the app on your Android or iOS device, use the following commands:

For Android:

npx expo run:android --device

For iOS:

npx expo run:ios --device

Now you can start scanning! Curious about how to set up different scanning modes or AR overlays? Check out the more extensive tutorial here, or navigate to our documentation.

Happy scanning! 🤳

FAQ

What is the main difference between react-native-vision-camera and expo-camera? 

The main difference between react-native-vision-camera and expo-camera lies in their approach to camera integration. 

react-native-vision-camera is a low-level, highly customizable native solution that gives developers detailed control over camera devices and frame processing. 

In contrast, expo-camera provides a higher-level, more structured implementation. Designed to work seamlessly within the Expo ecosystem, it focuses on ease of use and simple setup. However, this convenience comes at the cost of reduced flexibility and slower update cycles. 

Which library is easier to integrate for beginners? 

expo-camera is easier to integrate for beginners. It works out of the box within the Expo ecosystem, requires minimal setup, and includes clear documentation with example implementations.  

react-native-vision-camera, on the other hand, involves native configuration steps and a steeper learning curve but offers greater flexibility once set up. 

Why does react-native-vision-camera misread certain barcodes like EAN-13 or Code 128? 

These misreads stem from underlying ML Kit limitations. Aggregating multiple scans or using post-processing can reduce errors but may add latency. 

Related blog posts

Experience our demo apps

Barcode Icon Art

Barcode Scanner SDK

Scan 1D and 2D barcodes reliably in under 0.04s. Try features like Batch Scanning, Scan & Count, and our AR Overlays.

Launch Web Demo

Scan the code to launch the web demo on your phone.

Web QR Code

Also available to download from:

Document Icon Art

Document Scanner SDK

Scan documents quickly and accurately with our free demo app. Create crisp digital scans in seconds.

Launch Web Demo

Scan the code to launch the web demo on your phone.

Black and white QR code. Scan this code for quick access to information.

Also available to download from:

Data_capture Icon Art

Data Capture Modules

Try fast, accurate data capture with our demo app. Extract data from any document instantly – 100% secure.

Launch Web Demo

Scan the code to launch the web demo on your phone.

Black and white QR code. Scan this quick response code with your smartphone.

Also available to download from: