Camera Barcode Scanner on React Native CLI

Ezra Yeoshua
4 min readNov 16, 2022
Smartphone with a QR code

The best way to implement barcode scanning on React Native (without Expo) is using react-native-vision-camera, now that react-native-camera has been deprecated.

This article explains how to implement a camera barcode scanner within your React Native project.

To start, please ensure that you have set up your React Native project.

The required libraries are listed and explained in the following:

  • react-native-vision-camera —‘ VisionCamera by mrousavy’ provides many useful features for your camera app including Face Detection, Text Recognition, etc. However for this project, we will be focusing on its Barcode Scanning capabilities using its Frame Processor functions.
  • vision-camera-code-scanner — Thankfully, there are VisionCamera plugins out there already created by kind souls, which simplify this project even further. This plugin makes use of Google’s MLKit Vision Barcode Scanning API for reading various standard barcode/QR format commonly used today. Here are some of them.
  • react-native-reanimated — Since we need Frame Processors from VisionCamera and they run in Worklets, this library also needs to be installed.

We can now start the installation!

Please use your preferred package manager for the installation. This article will be using Yarn.

First, install react-native-vision-camera:

yarn add react-native-vision-camera

Next, for iOS, we need to install Pods:

cd ios && pod install && cd ../

Now we need to add Camera permissions for both Android and iOS:

For Android, add this line into the AndroidManifest.xml file inside the <manifest> tag:

<uses-permission android:name="android.permission.CAMERA" />

For iOS, add these into the Info.plist file inside the <dict> tag:

 <key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs access to your Camera.</string>

If you compile and build the project, react-native-vision-camera should be successfully installed!

We can now move on to installing the second library, react-native-reanimated:

yarn add react-native-reanimated

Next, open thebabel.config.js file and within its module.exports, add Reanimated’s Babel plugin:

module.exports = {
...
// Reanimated's Babel plugin here:
plugins: [
[
'react-native-reanimated/plugin',
{
globals: ['__scanCodes'],
},
],
],
};

CAUTION: According to Reanimated’s installation guide, this plugin must be listed last!

Also, adding the plugin may cause a worklet error, so it is advised to clean your application cache using:

  • yarn start --reset-cache

Finally, install the last library, vision-camera-code-scanner:

yarn add vision-camera-code-scanner

Again, for iOS, don’t forget to install Pods:

cd ios && pod install && cd ../

Now that the installations are done, compile and build your project and try the following example (full example at the very end). 😊

Add your imports:

import {useCameraDevices} from 'react-native-vision-camera';
import {Camera} from 'react-native-vision-camera';
import {useScanBarcodes, BarcodeFormat} from 'vision-camera-code-scanner';

We will be using vision-camera-code-scanner plugin’s hook called useScanBarcodes() for this example.

So, add these lines inside your component:

  const [hasPermission, setHasPermission] = React.useState(false);
const devices = useCameraDevices();
const device = devices.back;

// Here is where useScanBarcodes() hook is called.
// Specify your barcode format inside.
// Detected barcodes are assigned into the 'barcodes' variable.
const [frameProcessor, barcodes] = useScanBarcodes([BarcodeFormat.QR_CODE], {
checkInverted: true,
});

// Permissions added here.
React.useEffect(() => {
(async () => {
const status = await Camera.requestCameraPermission();
setHasPermission(status === 'authorized');
})();
}, []);

return (
device != null &&
hasPermission && (
<>
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
frameProcessor={frameProcessor}
frameProcessorFps={5}
/>
{barcodes.map((barcode, idx) => (
<View key={idx} style={{padding: 50}}>
<Text style={styles.barcodeTextURL}>{barcode.displayValue}</Text>
</View>
))}
</>
)
);

The full example is provided here by vision-camera-code-scanner.

Or you can view it here, too:

import * as React from 'react';

import { StyleSheet, Text } from 'react-native';
import { useCameraDevices } from 'react-native-vision-camera';
import { Camera } from 'react-native-vision-camera';
import { useScanBarcodes, BarcodeFormat } from 'vision-camera-code-scanner';

export default function App() {
const [hasPermission, setHasPermission] = React.useState(false);
const devices = useCameraDevices();
const device = devices.back;

const [frameProcessor, barcodes] = useScanBarcodes([BarcodeFormat.QR_CODE], {
checkInverted: true,
});

// Alternatively you can use the underlying function:
//
// const frameProcessor = useFrameProcessor((frame) => {
// 'worklet';
// const detectedBarcodes = scanBarcodes(frame, [BarcodeFormat.QR_CODE], { checkInverted: true });
// runOnJS(setBarcodes)(detectedBarcodes);
// }, []);

React.useEffect(() => {
(async () => {
const status = await Camera.requestCameraPermission();
setHasPermission(status === 'authorized');
})();
}, []);

return (
device != null &&
hasPermission && (
<>
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
frameProcessor={frameProcessor}
frameProcessorFps={5}
/>
{barcodes.map((barcode, idx) => (
<Text key={idx} style={styles.barcodeTextURL}>
{barcode.displayValue}
</Text>
))}
</>
)
);
}

const styles = StyleSheet.create({
barcodeTextURL: {
fontSize: 20,
color: 'white',
fontWeight: 'bold',
backgroundColor: 'red',
},
});

Here is a demo (CODE_39 format) picture on an iOS phone:

React Native app scanning barcode (BARCODE.CODE_39 format)

You’re done! Hope this helped! 👏👏👏

--

--