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

@vppos/react-native-nitro-nfc

v2.0.0

Published

React Native Nitro NFC reader for Vietnamese citizen ID chips

Readme

@vppos/react-native-nitro-nfc

React Native Nitro Module for reading Vietnamese citizen ID cards through NFC. It provides the native scan UI, PACE authentication, chip data parsing, progress events, and short-lived native caching. The npm package includes its Android AAR and iOS XCFrameworks, so an app does not need a separate NFC-core Maven or CocoaPods repository.

Requirements

  • React Native with the New Architecture enabled and react-native-nitro-modules.
  • Android API 24+ on a physical device with NFC enabled.
  • iOS 15+ on a physical device. Enable the Near Field Communication Tag Reading capability for the app's Apple Developer profile.

Android emulators and iOS Simulators cannot read an NFC chip.

Install

npm install @vppos/react-native-nitro-nfc react-native-nitro-modules

# iOS
cd ios && pod install && cd ..

Rebuild the native app after installation; reloading Metro is not enough.

npx react-native run-android
npx react-native run-ios --device

React Native and Nitro autolinking register the module automatically.

Native setup

Android

The library contributes NFC and vibration permissions through manifest merging. The host app must use minSdk 24 or higher:

android {
  defaultConfig {
    minSdk 24
  }
}

Do not add a :nfc-core Gradle project, a private NFC Maven repository, or NFC SDK credentials. The bundled nfc-core.aar is used automatically.

iOS

Configure both of the following in the host application target. They are different settings: Info.plist supplies the user-facing system message, while the entitlement authorizes NFC Tag Reading in the signed app.

  1. Add the NFC usage description and the ISO 7816 application identifiers to ios/<App>/Info.plist:
<key>NFCReaderUsageDescription</key>
<string>Ứng dụng sử dụng NFC để đọc dữ liệu từ thẻ căn cước công dân gắn chip.</string>

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
  <string>A0000002471001</string>
  <string>A0000002472001</string>
  <string>00000000000000</string>
</array>

Add these keys to the actual host app target's Info.plist, not only to a test target. Add only application identifiers approved for the card flows your app supports.

  1. In Xcode, select the app target, open Signing & Capabilities, and add Near Field Communication Tag Reading. Verify that the app's *.entitlements file contains at least:
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
  <string>TAG</string>
</array>

The entitlement must also be enabled in the Apple Developer provisioning profile used to sign the app. It is not enough to add only NFCReaderUsageDescription. The ISO 7816 identifiers above must be permitted by that profile. After changing either setting, run cd ios && pod install and rebuild the app on a physical iPhone.

Scan a card

The public NFCError class is the only error contract exposed by the package. It is used both in progress events and Promise rejections, with stable code and localized message fields.

import { NFCError, NFCSDK } from '@vppos/react-native-nitro-nfc';

export async function readCitizenCard(citizenId: string) {
  if (!NFCSDK.isAvailable()) {
    throw new Error('NFC is unavailable on this device.');
  }

  try {
    return await NFCSDK.scan({
      citizenId,
      readImage: true,
      cachePolicy: 'fresh',
      language: 'vi',
      onProgress(event) {
        if ('error' in event) {
          // Store this object directly in host UI state.
          const error: NFCError = event.error;
          console.warn(error.code, error.message);
          return;
        }

        // Update UI with event.progress, event.phase, and event.message.
      },
    });
  } catch (error) {
    if (error instanceof NFCError) {
      // The error has the same code/message shape as event.error.
      throw error;
    }
    throw error;
  }
}

citizenId must contain digits only and be at least six characters. A Vietnamese citizen ID normally has 12 digits; the core uses its last six digits as the CAN key.

scan() resolves to lightweight metadata (NFCScanResult). It includes the citizen details, a cached image URI when requested, and the sizes of available data groups. Set readImage: false to skip DG2/portrait reading when it is not needed.

Progress and errors

Normal progress events expose progress (0–100), message, and a stable phase: opening, waiting-for-tag, connecting, authenticating, reading, or success.

Errors are always exposed as { code, message }. The code is stable and is not localized; the message follows the requested language. Treat UserCanceled as a normal cancellation rather than a system failure.

scan() rejects with NFCError, whose code matches the stable native error code supplied in progress events. The rejection exposes the same code and message, so the host can store either value directly in one error state without parsing native error strings.

Use either the onProgress callback passed to scan() or the global NFCSDK.onProgress() listener for one UI state, not both, to avoid duplicate error handling.

Raw data and cache

Raw data groups are loaded only on demand. Prefer ArrayBuffer rather than Base64 to reduce memory use:

const dg1 = NFCSDK.getDataGroupBuffer('DG1');
const image = NFCSDK.getDataGroupBuffer('IMAGE');

// Clear metadata, chip image, and short-lived native cache when finished.
NFCSDK.clearCachedScan();

Supported group names are IMAGE, DG1, DG2, DG13, DG14, and SOD. With cachePolicy: 'reuse-if-valid', only DG2 can be reused when the DG1/SOD fingerprint matches; DG1 and SOD are still read from the chip.

Do not write raw DG bytes, portrait images, CAN, or citizen ID data to logs or analytics unless your data-handling policy explicitly permits it.

iOS OpenSSL mode

By default, the library uses a self-contained dynamic NFCCore.xcframework with private OpenSSL. This is the recommended mode.

If the host must supply its own compatible Swift module named OpenSSL, select the static host-OpenSSL variant before installing pods:

NITRO_NFC_USE_MANUAL_OPENSSL=1 pod install

The host is responsible for linking exactly one compatible OpenSSL provider in that mode. NFCSDK_USE_MANUAL_OPENSSL=1 remains supported as a legacy alias.

API

  • NFCSDK.isAvailable(): boolean
  • NFCSDK.scan(options): Promise<NFCScanResult>
  • NFCSDK.startScan(options): void
  • NFCSDK.onProgress(listener): NFCSubscription
  • NFCSDK.onScanResult(listener): NFCSubscription
  • NFCSDK.getDataGroupBuffer(name): ArrayBuffer | undefined
  • NFCSDK.getDataGroupBase64(name): string | undefined
  • NFCSDK.clearCachedScan(): void

See the repository's integration guide for the complete error and production test matrix.

License

MIT