npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pushpendersingh/react-native-scanner

v3.1.0

Published

A QR code & Barcode Scanner for React Native Projects.

Downloads

1,799

Readme

@pushpendersingh/react-native-scanner

React Native License Platform Version

A powerful, easy-to-use QR code & Barcode Scanner for React Native with New Architecture support


📖 About

A QR code & Barcode Scanner for React Native Projects.

For React Native developers that need to scan barcodes and QR codes in their apps, this package is a useful resource. It supports React Native's new Fabric Native architecture and was created in Kotlin (Android) and Swift (iOS) with Objective-C++ bridges.

With this package, users can quickly and easily scan barcodes and QR codes with their device's camera. Using this package, several types of codes can be scanned, and it is simple to use and integrate into your existing projects.

If you want to provide your React Native app the ability to read barcodes and QR codes, you should definitely give this package some thought.

The @pushpendersingh/react-native-scanner package also includes a flashlight feature that can be turned on and off. This can be useful when scanning QR codes & barcodes in low light conditions.


✨ Features

  • 📱 Cross-platform - Works on both iOS and Android
  • 🚀 New Architecture Ready - Built with Turbo Modules & Fabric
  • 📷 Camera Preview - Real-time camera feed with preview
  • 🔍 Multiple Formats - Supports 13+ barcode formats (QR, EAN, Code128, etc.)
  • High Performance - Optimized with CameraX (Android) & AVFoundation (iOS)
  • 🎯 Easy Integration - Simple API with event-based scanning
  • 💡 Flash Support - Toggle flashlight on/off
  • 🔄 Lifecycle Management - Automatic camera resource handling
  • 🔒 Thread-Safe - Modern concurrency patterns (Swift Actors & Kotlin synchronization)
  • 🎨 Customizable - Flexible styling options

📦 Installation

npm install @pushpendersingh/react-native-scanner

or

yarn add @pushpendersingh/react-native-scanner

iOS Setup

  1. Install CocoaPods dependencies:
cd ios && pod install && cd ..
  1. Add camera permission to Info.plist:
<key>NSCameraUsageDescription</key>
<string>We need camera access to scan barcodes</string>

Android Setup

Add camera permission to AndroidManifest.xml:

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

🎯 Usage

Basic Example

import React, { useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
import { BarcodeScanner, CameraView } from '@pushpendersingh/react-native-scanner';

export default function App() {
  const [scanning, setScanning] = useState(false);
  const [result, setResult] = useState('');

  const startScanning = async () => {
    try {
      setScanning(true);
      await BarcodeScanner.startScanning((barcodes) => {
        console.log('Barcodes detected:', barcodes);
        if (barcodes.length > 0) {
          const barcode = barcodes[0];
          setResult(`${barcode.type}: ${barcode.data}`);
        }
        stopScanning();
      });
    } catch (error) {
      console.error('Failed to start scanning:', error);
    }
  };

  const stopScanning = async () => {
    try {
      await BarcodeScanner.stopScanning();
      setScanning(false);
    } catch (error) {
      console.error('Failed to stop scanning:', error);
    }
  };

  return (
    <View style={styles.container}>
      <CameraView style={styles.camera} />
      
      <View style={styles.controls}>
        <TouchableOpacity 
          style={styles.button} 
          onPress={scanning ? stopScanning : startScanning}
        >
          <Text style={styles.buttonText}>
            {scanning ? 'Stop Scanning' : 'Start Scanning'}
          </Text>
        </TouchableOpacity>
        
        {result && (
          <View style={styles.resultContainer}>
            <Text style={styles.resultText}>{result}</Text>
          </View>
        )}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  camera: {
    flex: 1,
  },
  controls: {
    position: 'absolute',
    bottom: 50,
    left: 0,
    right: 0,
    alignItems: 'center',
  },
  button: {
    backgroundColor: '#007AFF',
    paddingHorizontal: 32,
    paddingVertical: 16,
    borderRadius: 8,
  },
  buttonText: {
    color: 'white',
    fontSize: 16,
    fontWeight: 'bold',
  },
  resultContainer: {
    marginTop: 16,
    backgroundColor: 'rgba(0,0,0,0.7)',
    padding: 16,
    borderRadius: 8,
  },
  resultText: {
    color: 'white',
    fontSize: 14,
  },
});

Scanning from Image (Gallery)

You can also scan QR codes and barcodes from existing images (e.g., from the gallery). This library only requires the image file path - it does not handle image picking.

To pick images from the gallery, you'll need a third-party library like react-native-image-picker. Please refer to that library's documentation for setup and required permissions (e.g., NSPhotoLibraryUsageDescription for iOS, READ_MEDIA_IMAGES for Android).

import { launchImageLibrary } from 'react-native-image-picker';
import { BarcodeScanner } from '@pushpendersingh/react-native-scanner';

const scanFromGallery = async () => {
  const result = await launchImageLibrary({ mediaType: 'photo' });
  
  if (result.assets && result.assets.length > 0) {
    const imageUri = result.assets[0].uri;
    if (imageUri) {
      try {
        const barcodes = await BarcodeScanner.scanImage(imageUri);
        if (barcodes.length > 0) {
          console.log('Found barcode:', barcodes[0].data);
        } else {
          console.log('No barcode found');
        }
      } catch (error) {
        console.error('Scan failed:', error);
      }
    }
  }
};

📚 API Reference

BarcodeScanner

startScanning(callback)

Starts the barcode scanning process.

BarcodeScanner.startScanning((barcodes: BarcodeResult[]) => {
  barcodes.forEach((barcode) => {
    console.log('Type:', barcode.type);
    console.log('Data:', barcode.data);
    console.log('Raw:', barcode.raw);
  });
});

Parameters:

  • callback: (barcodes: BarcodeResult[]) => void - Called when barcodes are detected

Returns: Promise<void>


scanImage(imageUri)

Scans a static image for barcodes. This is useful for scanning QR codes from gallery images, screenshots, or when live camera scanning fails on low-end devices.

Note: This method only requires the image file path/URI. It does not handle image picking - you'll need a third-party library like react-native-image-picker to select images from the gallery.

const barcodes = await BarcodeScanner.scanImage('file:///path/to/image.jpg');

Parameters:

  • imageUri: string - URI of the image file (supports file:// and content:// schemes)

Returns: Promise<BarcodeResult[]> - Array of detected barcodes

Supported Image Formats:

| Format | Android | iOS | Notes | |--------|---------|-----|-------| | JPEG/JPG | ✅ | ✅ | Full support | | PNG | ✅ | ✅ | Transparency handled (white background) | | WebP | ✅ | ✅ | iOS 14+ only | | GIF | ⚠️ | ⚠️ | First frame only | | BMP | ✅ | ✅ | Full support | | HEIF/HEIC | ✅ | ✅ | Android 8.0+, iOS 11+ | | TIFF | ❌ | ✅ | iOS only |

Not Supported: SVG, PDF, RAW (CR2, NEF, etc.), ICO, PSD


stopScanning()

Stops the barcode scanning process.

await BarcodeScanner.stopScanning();

Returns: Promise<void>


releaseCamera()

Releases the camera resources completely.

await BarcodeScanner.releaseCamera();

Returns: Promise<void>


enableFlashlight() / disableFlashlight()

Control the camera flashlight (torch) explicitly.

// Turn flashlight on
await BarcodeScanner.enableFlashlight();

// Turn flashlight off
await BarcodeScanner.disableFlashlight();

Returns: Promise<void>


hasCameraPermission()

Checks if camera permission is currently granted.

const hasPermission = await BarcodeScanner.hasCameraPermission();
console.log('Camera permission granted:', hasPermission);

Returns: Promise<boolean> - true if permission granted, false otherwise


requestCameraPermission()

Requests camera permission from the user with native promise resolution.

const granted = await BarcodeScanner.requestCameraPermission();
if (granted) {
  console.log('Permission granted!');
  // Start scanning
} else {
  console.log('Permission denied');
  // Show error or guide user to settings
}

Returns: Promise<boolean> - true if user grants permission, false if denied

Platform Support:

  • iOS: Fully supported with native callback
  • Android: Fully supported with native callback (API 23+)

Note: This method shows the native system permission dialog and waits for the user's response, then resolves the promise based on their choice.


CameraView

React component that renders the camera preview.

<CameraView style={{ flex: 1 }} />

Props:

  • style?: ViewStyle - Style for the camera view container

Types

BarcodeResult

interface BarcodeResult {
  type: string;      // Barcode format (e.g., 'QR_CODE', 'EAN_13')
  data: string;      // Decoded barcode data
  raw: string;       // Raw barcode value
}

🎨 Advanced Usage

Flashlight Control

import { BarcodeScanner } from '@pushpendersingh/react-native-scanner';

const [flashEnabled, setFlashEnabled] = useState(false);

const toggleFlash = async () => {
  try {
    if (flashEnabled) {
      await BarcodeScanner.disableFlashlight();
      setFlashEnabled(false);
    } else {
      await BarcodeScanner.enableFlashlight();
      setFlashEnabled(true);
    }
  } catch (err) {
    console.error('Failed to toggle flashlight', err);
  }
};

Lifecycle Management

import { useEffect } from 'react';
import { BarcodeScanner } from '@pushpendersingh/react-native-scanner';

useEffect(() => {
  // Start scanning on mount
  BarcodeScanner.startScanning(handleBarcode);

  // Cleanup on unmount
  return () => {
    BarcodeScanner.stopScanning();
    BarcodeScanner.releaseCamera();
  };
}, []);

Permission Handling

The library now provides built-in native camera permission methods that work seamlessly on both iOS and Android with proper promise resolution based on user response.

✅ Using Built-in Permission Methods (Recommended)

The library includes native methods that handle camera permissions with proper callbacks:

import React, { useEffect, useState } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { BarcodeScanner, CameraView } from '@pushpendersingh/react-native-scanner';

export default function App() {
  const [hasPermission, setHasPermission] = useState<boolean | null>(null);
  const [scanning, setScanning] = useState(false);

  useEffect(() => {
    checkPermission();
  }, []);

  const checkPermission = async () => {
    const granted = await BarcodeScanner.hasCameraPermission();
    setHasPermission(granted);
  };

  const requestPermission = async () => {
    const granted = await BarcodeScanner.requestCameraPermission();
    setHasPermission(granted);
    
    if (granted) {
      Alert.alert('Success', 'Camera permission granted!');
    } else {
      Alert.alert(
        'Permission Denied', 
        'Camera permission is required to scan barcodes'
      );
    }
  };

  const startScanning = async () => {
    // Check permission before scanning
    const granted = await BarcodeScanner.hasCameraPermission();
    
    if (!granted) {
      Alert.alert(
        'Permission Required',
        'Please grant camera permission to scan barcodes',
        [{ text: 'Grant Permission', onPress: requestPermission }]
      );
      return;
    }
    await BarcodeScanner.startScanning((barcodes) => {
      console.log('Scanned:', barcodes);
      BarcodeScanner.stopScanning();
      setScanning(false);
    });
  };

  if (hasPermission === null) {
    return <Text>Checking camera permission...</Text>;
  }

  if (hasPermission === false) {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text style={{ marginBottom: 20 }}>Camera permission not granted</Text>
        <Button title="Grant Permission" onPress={requestPermission} />
      </View>
    );
  }

  return (
    <View style={{ flex: 1 }}>
      <CameraView style={{ flex: 1 }} />
      <Button 
        title={scanning ? 'Stop Scanning' : 'Start Scanning'} 
        onPress={startScanning} 
      />
    </View>
  );
}

Key Features:

  • Cross-platform: Works on both iOS (API 10+) and Android (API 23+)
  • Promise-based: Returns true when granted, false when denied
  • Native callbacks: Waits for actual user response from system dialog
  • No dependencies: No need for additional permission libraries

Alternative: Using react-native-permissions

For more advanced permission handling (checking settings, handling blocked state, etc.), you can use react-native-permissions:

npm install react-native-permissions
# or
yarn add react-native-permissions
import { request, check, PERMISSIONS, RESULTS } from 'react-native-permissions';
import { Platform, Linking } from 'react-native';

const checkCameraPermission = async () => {
  const permission = Platform.select({
    ios: PERMISSIONS.IOS.CAMERA,
    android: PERMISSIONS.ANDROID.CAMERA,
  });

  const result = await check(permission);
  
  switch (result) {
    case RESULTS.GRANTED:
      return 'granted';
    case RESULTS.DENIED:
      return 'denied';
    case RESULTS.BLOCKED:
      return 'blocked';
    default:
      return 'unavailable';
  }
};

const requestCameraPermission = async () => {
  const permission = Platform.select({
    ios: PERMISSIONS.IOS.CAMERA,
    android: PERMISSIONS.ANDROID.CAMERA,
  });

  const result = await request(permission);
  
  if (result === RESULTS.BLOCKED) {
    // User has blocked permission, guide them to settings
    Alert.alert(
      'Permission Blocked',
      'Please enable camera permission in settings',
      [
        { text: 'Cancel', style: 'cancel' },
        { text: 'Open Settings', onPress: () => Linking.openSettings() },
      ]
    );
    return false;
  }
  
  return result === RESULTS.GRANTED;
};

📋 Supported Barcode Formats

This library supports a wide range of barcode formats across different categories:

| 1D Product | 1D Industrial | 2D | |:----------------------|:--------------|:---------------| | UPC-A | Code 39 | QR Code | | UPC-E | Code 93 | Data Matrix | | EAN-8 | Code 128 | Aztec | | EAN-13 | Codabar | PDF 417 | | | ITF | |

Format Details:

  • 1D Product Codes: Commonly used in retail (UPC-A, UPC-E, EAN-8, EAN-13)
  • 1D Industrial Codes: Used in logistics and inventory (Code 39, Code 93, Code 128, Codabar, ITF)
  • 2D Codes: High-density codes for storing more data (QR Code, Data Matrix, Aztec, PDF 417)

Total Supported Formats: 13 barcode types


🛠️ Technical Details

Android

  • CameraX 1.5.0 - Modern camera API with lifecycle awareness
  • ML Kit Barcode Scanning 17.3.0 - Google's ML-powered barcode detection
  • Kotlin - Native implementation with thread-safe synchronization
  • Thread Safety - Uses @Volatile and @Synchronized for concurrent access protection

iOS

  • AVFoundation - Native camera framework
  • Vision Framework - Apple's barcode detection
  • Swift 5.0+ - Native implementation with modern concurrency
  • Thread Safety - Uses Swift Actors for isolated state management and thread-safe operations

React Native

  • New Architecture - Turbo Modules + Fabric support
  • React Native 0.80+ - Minimum version requirement
  • Codegen - Automatic native interface generation

🔧 Troubleshooting

Camera Preview Not Showing

iOS:

  • Check camera permission in Info.plist
  • Ensure you're running on a physical device (simulator doesn't have camera)

Android:

  • Check camera permission in AndroidManifest.xml
  • Verify Google Play Services is installed

Barcode Not Scanning

  • Ensure good lighting conditions
  • Hold barcode steady and at proper distance
  • Check that barcode format is supported
  • Verify barcode is not damaged or distorted

Tips for scanning IMEI:

  • Ensure the IMEI barcode is clean and undamaged
  • Use good lighting (enable flashlight if needed)
  • Hold device steady at 10-15cm distance from the barcode
  • IMEI barcodes are usually found on device packaging or SIM trays

Build Issues

iOS:

cd ios && pod deintegrate && pod install && cd ..

Android:

cd android && ./gradlew clean && cd ..

📖 Example App

Check out the example app for a complete working implementation.

Run the example:

# Install dependencies
cd example && yarn

# iOS
cd example && npx pod-install && yarn ios

# Android
cd example && yarn android

🚀 Roadmap & Future Improvements

We're constantly working to improve this library. Here are some planned enhancements:

Planned Features

  • [ ] Barcode Generation - Add ability to generate barcodes/QR codes
  • [x] Image Analysis - Support scanning barcodes from gallery images
  • [ ] Advanced Camera Controls - Zoom, focus, and exposure controls

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Workflow

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes
  4. Run tests: yarn test
  5. Commit: git commit -m 'Add new feature'
  6. Push: git push origin feature/my-feature
  7. Open a Pull Request

Please read our Code of Conduct before contributing.


📄 License

MIT © Pushpender Singh


🙏 Acknowledgments


📞 Support


If you find this package helpful, please give it a ⭐️ on GitHub!