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

@2060.io/react-native-eid-reader

v0.3.1

Published

Reads passports and ID cards using its the device NFC.

Readme

react-native-eid-reader

npm version license platforms

A React Native module to read electronic passports and ID cards over NFC, following the ICAO Doc 9303 standard for Machine Readable Travel Documents (MRTDs).

Given the MRZ (Machine Readable Zone) information of a document — document number, date of birth and expiration date — or the Card Access Number (CAN) printed on the card, the library authenticates against the chip (PACE or BAC), reads the relevant data groups, and returns personal data and (optionally) the portrait image stored inside the document.

This module is used in production by Hologram Messaging as part of its real-world identity verification flows.

Features

  • 📖 Reads ICAO 9303 compliant electronic passports and national eID cards (TD1, TD2, TD3)
  • 🔐 PACE (Password Authenticated Connection Establishment) with automatic fallback to BAC (Basic Access Control)
    • PACE-MRZ — derived from document number + DOB + expiry
    • PACE-CAN — 6-digit Card Access Number (required by some eIDs, e.g. the German Personalausweis)
  • 🆔 Supports TD1 ID cards with extended (>9-char) document numbers (e.g. Moroccan CNIe)
  • 👤 Returns parsed personal data from DG1 (MRZ) and portrait image from DG2
  • 🗂️ Optional access to raw data groups (base64) for advanced use cases (PA, signature verification, …)
  • 🖼️ Helper to convert the embedded JPEG2000 portrait to JPEG so it can be displayed in a standard <Image />
  • 📡 NFC state & tag-discovered event listeners
  • ⚙️ NFC capability checks and deep-link into system NFC settings (Android)
  • 🤖 Android & 🍎 iOS support
  • 🏗️ New Architecture (TurboModules) ready

Requirements

| Platform | Minimum version | Notes | | -------- | --------------- | ------------------------------------------------------------------------------------ | | Android | API 24 (7.0) | Device must have NFC hardware. Required by React Native 0.76+. | | iOS | 16.0 | Physical device required; Simulator has no NFC. Requires the NFC capability & entitlement. PACE is only supported on iOS 26.4+; on earlier versions the library falls back to BAC. |

Installation

yarn add @2060.io/react-native-eid-reader
# or
npm install @2060.io/react-native-eid-reader

iOS

After installing the package, run pod install:

cd ios && pod install

Add the NFC capability to your app:

  1. In Xcode, enable Near Field Communication Tag Reading under Signing & Capabilities. This creates/updates your *.entitlements file with:

    <key>com.apple.developer.nfc.readersession.formats</key>
    <array>
      <string>TAG</string>
    </array>
  2. Add the following keys to your Info.plist:

    <key>NFCReaderUsageDescription</key>
    <string>This app uses NFC to read your ID document</string>
    
    <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
    <array>
      <string>A0000002471001</string>
      <string>A0000002472001</string>
      <string>00000000000000</string>
    </array>

Android

No manual steps are required — the library's manifest already declares the NFC permission and autolinking takes care of the rest.

Usage

import EIdReader, {
  type EIdReadResult,
} from '@2060.io/react-native-eid-reader';

async function scan() {
  // NFC state & tag events (optional)
  EIdReader.addOnNfcStateChangedListener((state) => console.log('NFC', state));
  EIdReader.addOnTagDiscoveredListener(() => console.log('Tag discovered'));

  try {
    // Option A — MRZ-based authentication (BAC / PACE-MRZ)
    const result: EIdReadResult = await EIdReader.startReading({
      mrzInfo: {
        documentNumber: 'ABC123456',  // 9-char alphanumeric, or the full extended
                                      // document number for TD1 cards that have one
        birthDate: '990101',          // YYMMDD
        expirationDate: '341231',     // YYMMDD
      },
      includeImages: true,
      includeRawData: false,
    });

    // Option B — CAN-based authentication (PACE-CAN)
    //   Used by eIDs that do not accept BAC/PACE-MRZ. The CAN is a 6-digit
    //   code printed on the card (e.g. the German Personalausweis).
    // const result: EIdReadResult = await EIdReader.startReading({
    //   can: '123456',
    //   includeImages: true,
    // });

    if (result.status === 'OK') {
      console.log(result.data.firstName, result.data.lastName);

      if (result.data.originalFacePhoto) {
        // The portrait is JPEG2000; convert to JPEG so <Image/> can render it
        const jpegDataUrl = EIdReader.imageDataUrlToJpegDataUrl(
          `data:image/jp2;base64,${result.data.originalFacePhoto}`
        );
        // <Image source={{ uri: jpegDataUrl }} />
      }
    }
  } catch (e) {
    console.error(e);
  } finally {
    EIdReader.stopReading();
    EIdReader.removeListeners();
  }
}

See the example app for a fuller, runnable integration (including input UI for the MRZ fields).

API

startReading(params): Promise<EIdReadResult>

Starts an NFC reading session. On iOS this presents the system NFC sheet; on Android the user must hold the document against the back of the phone.

Exactly one of mrzInfo or can must be supplied.

| Param | Type | Default | Description | | ---------------- | ----------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------ | | mrzInfo | { documentNumber, birthDate, expirationDate } | — | MRZ-derived key for BAC / PACE-MRZ. Dates in YYMMDD format. documentNumber may be longer than 9 chars for TD1 cards with an extended document number. | | can | string (6 digits) | — | Card Access Number for PACE-CAN. Supported on both iOS and Android, though Android support is untested in-house — we have no CAN-only eID to exercise it against. Reports welcome. | | includeImages | boolean | false | Include the portrait photo from DG2 | | includeRawData | boolean | false | Include raw data groups as base64 | | labels | object | — | Strings shown in the iOS NFC sheet & errors |

Returns an EIdReadResult whose status is 'OK' | 'Error' | 'Canceled'.

Authentication protocol used

The library picks the strongest access protocol the card advertises:

  1. PACE (preferred) — negotiated automatically when the card publishes PACEInfo in EF.CardAccess.
    • PACE-MRZ when mrzInfo is supplied.
    • PACE-CAN when can is supplied. Android path is untested in-house (see the can row above).
  2. BAC — automatic fallback when PACE is not supported or fails, using the MRZ key. Only meaningful with mrzInfo; eIDs that refuse BAC (e.g. French CNIe) will simply report the PACE failure.

stopReading(): void

Aborts the current reading session.

isNfcSupported(): Promise<boolean>

Whether the device has NFC hardware.

isNfcEnabled(): Promise<boolean>

Whether NFC is currently turned on (Android).

openNfcSettings(): Promise<boolean>

Opens the system NFC settings screen (Android).

imageDataUrlToJpegDataUrl(dataUrl): string

Converts a JPEG2000 data URL (as produced by the passport chip for the portrait) to a JPEG data URL that standard <Image /> components can render.

Events

  • addOnTagDiscoveredListener(cb) — fires when an NFC tag enters the field
  • addOnNfcStateChangedListener(cb) — fires when NFC is turned on/off ('on' | 'off')
  • removeListeners() — removes all listeners added by this module

Running the example

yarn
yarn example start         # Metro
yarn example android       # or
yarn example ios           # (after `cd example/ios && pod install`)

Standards & references

Acknowledgements & project history

This module stands on the shoulders of two excellent open-source projects:

At the time we added iOS support, consuming NFCPassportReader as a normal Swift/CocoaPods dependency was impractical in a React Native context for two reasons:

  1. OpenSSL version conflicts — the library depends on a specific OpenSSL-Universal version, and resolving it alongside other transitive pods in a React Native app was fragile.
  2. Swift-only module integration — React Native's iOS build setup around that era required use_frameworks! to consume Swift-only pods, which interacted poorly with Hermes and static React-Core pods.

As a pragmatic workaround, we vendored the relevant Swift sources into ios/NFCPassportReader/ and pinned OpenSSL-Universal at the podspec level.

Roadmap

Our long-term plan is to remove the vendored fork and converge on the upstream projects:

  1. Contribute bug fixes we've accumulated back to AndyQ/NFCPassportReader.
  2. Consume NFCPassportReader as a proper Swift dependency (CocoaPods or SPM) now that modern React Native (0.76+) has much better Swift interop.
  3. Eventually, contribute the iOS implementation back to batuhanoztrk/react-native-nfc-passport-reader so the ecosystem converges on a single, cross-platform library.

Contributions toward any of these goals are very welcome — see CONTRIBUTING.md.

Contributing

See CONTRIBUTING.md for the dev workflow and how to submit pull requests.

License

MIT © 2060.io