Skip to main content

Working with Barcode and QR Codes

1. Scanning Barcodes

Property Description Values
barCodeTypes Array of barcode types to scan ['ean13', 'ean8', 'upc', 'upce', 'code39', 'code128', 'codabar', 'i2of5', 'itf14', 'qr', 'pdf417', 'aztec']
onBarCodeScanned Callback function when a barcode is scanned Function with { data, type } parameter
flashMode Flashlight mode for scanning 'auto', 'on', 'off', 'torch'

Example: Basic Barcode Scanner

import { BarCodeScanner } from 'expo-barcode-scanner';
import { useState, useEffect } from 'react';

export default function BarcodeScanner() {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

  useEffect(() => {
    (async () => {
      const { status } = await BarCodeScanner.requestPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);

  const handleBarCodeScanned = ({ data, type }) => {
    setScanned(true);
    alert(`Scanned ${type}: ${data}`);
  };

  if (hasPermission === null) {
    return <View style={{ flex: 1 }}><Text>Requesting camera permission</Text></View>;
  }

  if (hasPermission === false) {
    return <View style={{ flex: 1 }}><Text>No access to camera</Text></View>;
  }

  return (
    <View style={{ flex: 1 }}>
      <BarCodeScanner
        onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
        barCodeTypes={[BarCodeScanner.Constants.BarCodeType.qr]}
        style={{ flex: 1 }}
      />
    </View>
  );
}
Note: Ensure camera permissions are requested before using the scanner.
Warning: The scanner stops scanning once a code is detected unless scanned is reset.

2. Configuring Barcode Types

Barcode Type Description Supported in Expo Notes
CODE_128 128-character alphanumeric barcode NEW Most commonly used for inventory management
CODE_39 39-character alphanumeric barcode Yes Used in retail and manufacturing
EAN_13 13-digit European Article Number Yes Standard for retail products
EAN_8 8-digit European Article Number Yes Shorter version of EAN-13
UPC_A 12-digit Universal Product Code Yes Common in North America
QR_CODE 2D QR code with variable data capacity NEW Used for web links, contact info, etc.

Example: Scanning QR Code

import { BarCodeScanner } from 'expo-barcode-scanner';

const scanQRCode = async () => {
  const { status } = await BarCodeScanner.requestPermissionsAsync();
  if (status === 'granted') {
    const result = await BarCodeScanner.scanFromCameraAsync({
      barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr]
    });
    console.log('Scanned:', result.data);
  }
};

3. Using expo-barcode-scanner

Property Description Default Notes
barCodeTypes Array of barcode types to scan for ['qr', 'ean13', 'ean8', 'upce', 'code128', 'code39', 'codabar', 'i25', 'itf14', 'pdf417'] Supports multiple barcode types
onBarCodeScanned Callback function when a barcode is scanned null Receives { data, type } object
flashMode Flashlight mode for scanning 'auto' Options: 'off', 'on', 'auto', 'torch'

Example: Scanning QR Codes

import { BarCodeScanner } from 'expo-barcode-scanner';
import { useState, useEffect } from 'react';

export default function QRScanner() {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

  useEffect(() => {
    (async () => {
      const { status } = await BarCodeScanner.requestPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);

  const handleBarCodeScanned = ({ data }) => {
    setScanned(true);
    alert(`Scanned: ${data}`);
  };

  if (hasPermission === null) {
    return <View><Text>Requesting camera permission</Text></View>;
  }
  if (hasPermission === false) {
    return <View><Text>No access to camera</Text></View>;
  }

  return (
    <View style={{ flex: 1, flexDirection: 'column' }}>
      <BarCodeScanner
        onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
        barCodeTypes={[BarCodeScanner.Constants.BarCodeType.qr]}
        style={{ flex: 1, width: '100%' }}
      />
    </View>
  );
}
Note: Ensure camera permissions are requested before using the scanner.
Warning: The scanner will stop scanning once a barcode is detected unless you set scanned to false.

4. Handling Scanned Data

Property Description Example
data The scanned data as a string "https://expo.dev"
type Type of the scanned code (e.g., QR_CODE, AZTEC) "QR_CODE"
bounds Bounds of the scanned code in the image { origin: { x: 10, y: 20 }, size: { width: 100, height: 100 } }

Example: Processing Scanned Data

import { BarCodeScanner } from 'expo-barcode-scanner';

const handleBarCodeScanned = ({ data, type }) => {
  console.log(`Scanned ${type}:`, data);
  if (type === 'QR_CODE') {
    // Handle QR code
    console.log('QR Code data:', data);
  } else if (type === 'EAN_13') {
    // Handle EAN-13 barcode
    console.log('EAN-13 data:', data);
  }
};
Note: The data property contains the actual scanned content, which could be a URL, text, or other data depending on the barcode type.

5. Generating QR Codes

Property Description Example
value The data to encode into the QR code "https://expo.dev"
size Size of the QR code in pixels 200
backgroundColor Background color of the QR code "#ffffff"
foregroundColor Color of the QR code modules "#000000"

Example: Basic QR Code Generation

import { BarCodeScanner } from 'expo-barcode-scanner';\n\nconst qrCodeData = "https://expo.dev";\nconst size = 200;\n\n// Generate QR code with default settings\n<BarCodeScanner\n  value={qrCodeData}\n  format="QR_CODE"\n  size={size}\n  backgroundColor="#ffffff"\n  foregroundColor="#000000"\n/>

Example: Custom Styled QR Code

import { BarCodeScanner } from 'expo-barcode-scanner';\n\nconst qrCodeData = "https://expo.dev";\nconst size = 300;\n\n// Generate QR code with custom colors and size\n<BarCodeScanner\n  value={qrCodeData}\n  format="QR_CODE"\n  size={size}\n  backgroundColor="#f0f0f0"\n  foregroundColor="#333333"\n/>

6. Customizing QR Appearance

Property Values Description
backgroundColor "#ffffff" Background color of the QR code
foregroundColor "#000000" Color of the QR code modules
size 200 Size of the QR code in pixels
margin 1 Margin around the QR code in modules

Example: Customizing QR Code Appearance

import { BarCodeScanner } from 'expo-barcode-scanner';

<BarCodeScanner
  onBarCodeScanned={handleBarCodeScanned}
  backgroundColor="#ffffff"
  foregroundColor="#000000"
  size={250}
  margin={2}
/>

7. Embedding Logos in QR

Property Description Values
logo Image to embed in the center of the QR code string (URI or base64 encoded image)
logoSize Size of the logo in pixels number
logoBackgroundColor Background color behind the logo string (hex or CSS color)

Example: Embedding a Logo in QR Code

import { BarCodeScanner } from 'expo-barcode-scanner';

const qrData = {
  logo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==',
  logoSize: 40,
  logoBackgroundColor: '#ffffff'
};

// Generate QR code with embedded logo
const qrCode = await BarCodeScanner.generate({
  ...qrData,
  value: 'https://expo.dev',
  format: 'QR_CODE'
});
Note: The logo must be a square image and should not exceed 20% of the QR code size to maintain scannability.

8. Scanning Multiple Barcodes

Example: Scanning Multiple Barcodes

import { BarCodeScanner } from 'expo-barcode-scanner';
import { useState } from 'react';

export default function MultiBarcodeScanner() {
  const [scannedBarcodes, setScannedBarcodes] = useState([]);

  const handleBarCodeScanned = ({ data, type }) => {
    setScannedBarcodes(prev => [...prev, { data, type }]);
  };

  return (
    <BarCodeScanner
      onBarCodeScanned={handleBarCodeScanned}
      style={{ flex: 1 }}
    />
  );
}
Property Description Notes
onBarCodeScanned Callback function when a barcode is scanned Receives an object with data and type
scannedBarcodes Array of scanned barcode data Each item is an object with data and type
Note: The scanner will continue to detect barcodes until the component is unmounted or onBarCodeScanned is set to null.

9. Using Barcode Overlay

Example: Scanning Barcode with Overlay

import { BarCodeScanner } from &#x27;expo-barcode-scanner&#x27;;
import { View, StyleSheet } from &#x27;react-native&#x27;;

export default function BarcodeScanner() {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

  useEffect(() => {
    (async () => {
      const { status } = await BarCodeScanner.requestPermissionsAsync();
      setHasPermission(status === &#x27;granted&#x27;);
    })();
  }, []);

  const handleBarCodeScanned = ({ data }) => {
    setScanned(true);
    alert(`Scanned: ${data}`);
  };

  if (hasPermission === null) {
    return <View style={styles.container}><Text>Requesting camera permission</Text></View>;
  }

  if (hasPermission === false) {
    return <View style={styles.container}><Text>No access to camera</Text></View>;
  }

  return (
    <View style={styles.container}>
      <BarCodeScanner
        onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
        style={StyleSheet.absoluteFillObject}
        formats={[BarCodeScanner.Constants.BarCodeType.code128]}
      />
      <View style={styles.overlay}>
        <View style={styles.scanArea}></View>
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: &#x27;column&#x27;,
  },
  overlay: {
    position: &#x27;absolute&#x27;,
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: &#x27;center&#x27;,
    alignItems: &#x27;center&#x27;,
  },
  scanArea: {
    width: 200,
    height: 200,
    borderWidth: 2,
    borderColor: &#x27;#fff&#x27;,
    borderRadius: 10,
  },
});
Property Description Values
formats Barcode types to scan [BarCodeScanner.Constants.BarCodeType.code128]
onBarCodeScanned Callback when a barcode is scanned Function that receives { data }
style Styling for the scanner view StyleSheet.absoluteFillObject
Note: The overlay is a visual guide to help users align the barcode within the scan area.

10. Handling Invalid Scans

Example: Basic Scan Error Handling

import { BarCodeScanner } from &#x27;expo-barcode-scanner&#x27;;

const handleScan = (data, type) => {
  if (!data) {
    console.warn("Scan failed or cancelled");
    return;
  }

  try {
    const parsedData = JSON.parse(data);
    console.log("Scanned data:", parsedData);
  } catch (error) {
    console.error("Invalid scan data format", error);
  }
};

const handleBarCodeScanned = ({ data, type }) => {
  if (type === BarCodeScanner.Constants.BarCodeType.qr) {
    handleScan(data, type);
  } else {
    console.warn("Unsupported barcode type", type);
  }
};
Property Description Notes
data Scanned data string May be null or empty for invalid scans
type Barcode type identifier Use BarCodeScanner.Constants.BarCodeType
cancelled Boolean indicating if scan was cancelled Set to true when user cancels scan
Note: Always validate scanned data before processing to prevent runtime errors from malformed input.
Warning: Never assume all scanned data is valid JSON or parseable content. Always wrap parsing logic in try/catch blocks.

Best Practices for Invalid Scan Handling

  • Check for null or empty data values
  • Validate barcode type before processing
  • Wrap data parsing in try/catch blocks
  • Provide user feedback for failed scans
  • Log invalid scan attempts for debugging

11. Setting Scan Area

Property Description Default Notes
scanArea Defines the rectangular area within the camera view where barcodes can be detected. It's an object with x, y, width, and height properties, all in normalized coordinates (0 to 1). { x: 0, y: 0, width: 1, height: 1 } Only the area defined by this rectangle will be scanned for barcodes. Useful to focus scanning on specific regions of the camera feed.

Example: Define a Custom Scan Area

import { BarCodeScanner } from 'expo-barcode-scanner';

const scanArea = {
  x: 0.25,
  y: 0.25,
  width: 0.5,
  height: 0.5
};

// Use in BarCodeScanner
<BarCodeScanner
  onBarCodeScanned={handleBarCodeScanned}
  scanArea={scanArea}
/>

12. Using Torch for Scanning

Property Description Values
torch Enables or disables torch (flashlight) for scanning true / false
torchMode Controls torch behavior "on", "off", "auto"

Example: Enable Torch for Scanning

import { BarCodeScanner } from 'expo-barcode-scanner';

const App = () => {
  const [hasPermission, setHasPermission] = useState(null);
  const [scanned, setScanned] = useState(false);

  useEffect(() => {
    (async () => {
      const { status } = await BarCodeScanner.requestPermissionsAsync();
      setHasPermission(status === 'granted');
    })();
  }, []);

  const handleBarCodeScanned = ({ data }) => {
    setScanned(true);
    alert(`Scanned: ${data}`);
  };

  if (hasPermission === null) {
    return <View style={styles.container}><Text>Requesting camera permission</Text></View>;
  }

  if (hasPermission === false) {
    return <View style={styles.container}><Text>No access to camera</Text></View>;
  }

  return (
    <View style={styles.container}>
      <BarCodeScanner
        onBarCodeScanned={handleBarCodeScanned}
        torchMode="on"
        style={StyleSheet.absoluteFillObject}
      />
    </View>
  );
};
Note: The torch mode only works on devices that support flashlight functionality.
Warning: Enabling torch may drain battery faster. Use it only when necessary.

Was this article helpful?