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

react-native-scan-aadhaar-card

v0.3.5

Published

High-accuracy native Aadhaar (UIDAI) QR code scanner for React Native. Supports the dense Secure QR (2019+) and legacy XML formats, gallery import, torch, pinch-to-zoom and tap-to-focus.

Readme

react-native-scan-aadhaar-card

High-accuracy native Aadhaar (UIDAI) QR code scanner for React Native.

Physical Aadhaar cards use the densest standard QR code (version 40, 177×177 modules), which most generic scanner libraries fail to read reliably. This library wraps purpose-built native scanners:

Features

  • Full-screen native scanner UI: dimmed viewfinder, torch, pinch-to-zoom, tap-to-focus.
  • Scan from the camera or import from the gallery / photo library.
  • Returns parsed, privacy-safe fields (masked Aadhaar number, name, DOB, address, hashes, optional photo).
  • Customizable title, hints, accent / overlay colors, toggles, timeout, and error messages.
  • TypeScript types included.

Installation

npm install react-native-scan-aadhaar-card
# or
yarn add react-native-scan-aadhaar-card

iOS

cd ios && pod install

Add the usage description strings to your app's Info.plist:

<key>NSCameraUsageDescription</key>
<string>We need the camera to scan your Aadhaar QR code.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need photo access to scan an Aadhaar QR from your gallery.</string>

Minimum iOS deployment target: 13.0.

Android

The android.permission.CAMERA permission and the scanner Activity are merged automatically from the library's manifest — no manual edits required. Minimum minSdkVersion: 24.

After yarn add / npm install, you MUST rebuild native code — Metro JS reload is not enough. Run npx react-native run-android or cd android && ./gradlew :app:assembleDebug.

The camera permission is requested at runtime by the scanner itself; you do not need to request it beforehand.

Compatibility matrix

| React Native | Architecture | JS bridge | Android native | Supported | |---|---|---|---|---| | 0.74 | Old Arch (newArchEnabled=false) | NativeModules.ScanAadhaarCard fallback | ScanAadhaarCardModule via ReactPackage | ✅ | | 0.76+ | New Arch (newArchEnabled=true) | TurboModuleRegistry.get('ScanAadhaarCard') | Codegen NativeScanAadhaarCardSpec | ✅ | | 0.72 – 0.73 | Old Arch | NativeModules fallback | ScanAadhaarCardModule via ReactPackage | ✅ |

| Consumer toolchain | How the library adapts | |---|---| | Kotlin 1.9.x | Reads rootProject.ext.kotlinVersion first; fallback 1.9.24 in android/gradle.properties | | AGP 8.6+ | No pinned AGP in library — uses consumer Gradle plugin version | | Expo 50–52 | Same autolinking; rebuild native after install |

NativeScanAadhaarCard.ts resolves the module lazily: TurboModule first, then NativeModules — so RN 0.74 Old Arch and RN 0.76+ New Arch both work without app-side bridge code.

No manual configuration needed:

  • No patch-package
  • No bridge Kotlin files in your app
  • No android: null in react-native.config.js
  • No manual settings.gradle / app/build.gradle entries
  • No implementation "androidx.databinding:viewbinding:..." in your app
  • No useTurboModules / DefaultTurboModuleManagerDelegate changes

Android + React Native <Modal>

The native scanner runs as a full-screen Activity. If you call scanAadhaar() while a RN <Modal> is visible, the scanner may appear behind the modal on some devices. Hide the modal first:

setModalVisible(false);
// Wait one frame for the modal to dismiss before launching the scanner
await new Promise(resolve => setTimeout(resolve, 100));
const data = await scanAadhaar();

Usage

import {
  scanAadhaar,
  fullAddress,
  displayGender,
  AadhaarScanError,
} from 'react-native-scan-aadhaar-card';

async function handleScan() {
  try {
    const data = await scanAadhaar({
      title: 'Scan Aadhaar QR',
      accentColor: '#2E7D32',
      enableGallery: true,
      enableTorch: true,
      includePhoto: true,
    });

    console.log(data.name, data.uid);          // "Rahul Kumar"  "XXXX XXXX 1234"
    console.log(displayGender(data));           // "Male"
    console.log(fullAddress(data));             // "123, Main Street, ..."
  } catch (e) {
    if (e instanceof AadhaarScanError) {
      if (e.code === 'CANCELLED') return;       // user closed the scanner
      console.warn(e.code, e.message);
    } else {
      throw e;
    }
  }
}

API

scanAadhaar(options?: AadhaarScanOptions): Promise<AadhaarData>

Launches the native full-screen scanner. Resolves with the parsed data, or rejects with an AadhaarScanError.

fullAddress(data: AadhaarData): string

Comma-separated single-line address from the populated address fields.

displayGender(data: AadhaarData): string

Maps "M" / "F" / "T" to "Male" / "Female" / "Transgender".

Options

| Option | Type | Default | Description | | --- | --- | --- | --- | | title | string | "Scan Aadhaar QR" | Title shown at the top of the scanner. | | scanHint | string | "Align the QR code within the frame" | Primary hint under the frame. | | zoomHint | string | "Tap to focus · Pinch to zoom" | Secondary hint. | | enableGallery | boolean | true | Show the "scan from gallery" button. | | enableTorch | boolean | true | Show the torch / flash toggle. | | accentColor | string | platform default | Color of the scan frame + scan line. | | overlayColor | string | ~55% black | Dimmed overlay color. Accepts #RRGGBB or #AARRGGBB. | | includePhoto | boolean | false | Include the embedded card photo as base64 PNG (iOS only for now). | | includeRawValue | boolean | false | Include the exact raw QR string (PII — see below). | | timeoutMs | number | 30000 | Hard cap on a single gallery decode. | | invalidQrMessage | string | — | Override the "not a valid Aadhaar QR" message. | | noQrInImageMessage | string | — | Override the "no QR in image" message. | | scanTimeoutMessage | string | — | Override the timeout message. | | permissionDeniedMessage | string | — | Override the permission-denied message. |

Result — AadhaarData

| Field | Notes | | --- | --- | | uid | Masked Aadhaar number, e.g. "XXXX XXXX 1234" (full number is never in the QR). | | name, gender, dateOfBirth, yearOfBirth | Identity fields. gender is the raw M/F/T code. | | careOf, house, street, landmark, locality, vtc, district, state, pincode | Address fields. | | mobileHash, emailHash | SHA-256 hashes (not reversible), when present. | | photoBase64? | Base64 PNG of the embedded photo, only when includePhoto is set (iOS). | | rawValue? | Exact scanned QR string, only when includeRawValue is set. Treat as PII. |

About rawValue and privacy

The full Aadhaar number is never present in the QR — only the last 4 digits are recoverable. Mobile/email are stored as SHA-256 hashes. The raw QR payload is considered PII (for new cards it's the long Secure QR decimal string), so it is not returned by default. Enable includeRawValue: true only if you genuinely need it; even then it is never logged by the native code.

Error handling

scanAadhaar rejects with an AadhaarScanError exposing a .code:

| Code | Meaning | | --- | --- | | CANCELLED | The user closed the scanner. | | PERMISSION_DENIED | Camera permission was denied. | | UNAVAILABLE | No host Activity/ViewController, or a scan is already in progress. | | UNKNOWN | Unexpected native failure. |

Note: an unreadable / non-Aadhaar QR does not reject — the scanner shows an inline message and keeps scanning so the user can retry.

Architecture support

Works under both the legacy bridge and the New Architecture (TurboModules / bridgeless via the interop layer). No extra configuration required.

Credits

QR decode/parse pipeline reverse-engineered from physical UIDAI Aadhaar cards. See docs/AADHAAR_QR_SCANNING.md for the format notes.

License

MIT


Changelog

v0.3.5

No API changes. Rebuild native after upgrading.

| Area | v0.3.4 | v0.3.5 | |---|---|---| | Android distribution | Precompiled AAR | Kotlin source (consumer Gradle compile) | | RN 0.74 Old Arch | NativeModules fallback | Unchanged | | RN 0.76+ New Arch | TurboModule codegen | Unchanged | | Kotlin / AGP | AAR wrapper + pinned deps | Consumer kotlinVersion 1.9.x + AGP 8.6+ |

v0.2.0

No breaking changes. API, options, and return types are identical to v0.1.0.

What changed

| Area | v0.1.0 | v0.2.0 | |---|---|---| | scanAadhaar() API | — | Unchanged | | AadhaarScanOptions props | — | Unchanged | | AadhaarData fields | — | Unchanged | | Error codes | CANCELLED, PERMISSION_DENIED, UNAVAILABLE, UNKNOWN | Added: NO_QR_FOUND, INVALID_QR, TIMEOUT | | Android zxing-cpp version | 3.0.2 | 2.3.0 (see note below) | | Android Gradle Plugin | not pinned | 8.6.0 | | Kotlin version | not pinned | 1.9.24 (configurable via gradle.properties) | | iOS native code shipped | Swift source files | Precompiled XCFramework binary | | Android native code shipped | Kotlin source files | Precompiled AAR | | JS code shipped | TypeScript source | Minified compiled JS only |

New error codes in v0.2.0

The following AadhaarScanError codes were added. They were previously returned as UNKNOWN:

| Code | Meaning | |---|---| | NO_QR_FOUND | Gallery image was processed but contained no QR code. | | INVALID_QR | A QR code was found but it is not a valid Aadhaar QR. | | TIMEOUT | Gallery decode exceeded timeoutMs (default 30 000 ms). |

If you previously caught all errors with e.code === 'UNKNOWN', update your handler to also check for these codes if you want to show specific messages to the user.

Android zxing-cpp version note

v0.2.0 ships with zxing-cpp:android:2.3.0 for compatibility with Android Gradle Plugin 8.6 and older NDK toolchains.

Upgrading to v0.3.0 (planned): When you upgrade your project to AGP ≥ 8.7, install v0.3.0 of this library which will restore zxing-cpp:3.0.2. That version decodes dense Aadhaar Secure QR codes more reliably on newer hardware. No API changes are planned.

// When ready to upgrade:
"react-native-scan-aadhaar-card": "^0.3.0"

v0.1.0

Initial release.