@capgo/capacitor-nfc

中文文档
8.3.7发布于 2026/11/09MPL-2.0TypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 11.8万

Native NFC tag discovery, reading and writing for Capacitor apps on iOS and Android.

原始使用文档
文档目录30 节
  1. ➡️ Get started for free
  2. Key features
  3. Supported Tag Types
  4. Documentation
  5. Compatibility
  6. Install
  7. Usage
  8. Checking NFC hardware support
  9. Reading NDEF tags (default behavior)
  10. Reading raw tags (iOS) - Get UID from unformatted tags
  11. Handling iOS session endings
  12. API
  13. startScanning(...)
  14. stopScanning()
  15. write(...)
  16. erase()
  17. makeReadOnly()
  18. transceive(...)
  19. share(...)
  20. unshare()
  21. getStatus()
  22. showSettings()
  23. getPluginVersion()
  24. isSupported()
  25. addListener('nfcEvent', ...)
  26. addListener('tagDiscovered' | 'ndefDiscovered' | 'ndefMimeD…
  27. addListener('nfcStateChange', ...)
  28. addListener('nfcSessionEnd', ...)
  29. Interfaces
  30. Type Aliases

@capgo/capacitor-nfc

Read and write NFC tags from your Capacitor app on iOS and Android. A modern Capacitor port of the battle-tested phonegap-nfc plugin.

Capgo - Build Capacitor apps with AI, ship updates instantly

Capgo: push fixes to your Capacitor users in minutes, build signed iOS and Android apps without a Mac, and roll back in one click.

➡️ Get started for free

14-day unlimited free trial. No credit card required

🤖 Building with an AI coding agent? Install Capgo skills so Claude Code, Codex, Cursor, Copilot, or Gemini CLI know how to install and use @capgo/capacitor-nfc in your Capacitor app: npx skills add Cap-go/capgo-skills. Then ask your agent: "Add @capgo/capacitor-nfc to my Capacitor app and wire it up." Agent setup guides · Hosted MCP

@capgo/capacitor-nfc for Capacitor apps

Key features

  • Scan tags: startScanning() and stopScanning(), with tagDiscovered and nfcEvent listeners.
  • Write NDEF: write() sends NDEF records to the last discovered tag. On iOS, keep the session open with invalidateAfterFirstRead: false.
  • Tag management: erase(), plus makeReadOnly() on Android.
  • Adapter status: isSupported(), getStatus(), showSettings() and the nfcStateChange event.
  • iOS session options: NDEF or tag sessions, polling options and a custom alert message.
  • Android P2P: share() and unshare() for peer-to-peer messages, before Android 10 only.
  • Platforms: iOS and Android. iOS uses Core NFC, Android uses NfcAdapter. Not available on web.

Native NFC tag detection, reading, and writing for Capacitor apps on iOS and Android.

Modern Capacitor port of the battle-tested phonegap-nfc plugin, aligned with Capgo conventions and tooling.

Supported Tag Types

  • Standard NFC Forum Tags (Type 1-4)
  • MIFARE Ultralight - Full support for reading NDEF data from MIFARE Ultralight tags, including EV1 and NTAG variants. The plugin automatically detects MIFARE Ultralight cards and extracts NDEF messages in addition to standard NFC tags.

Documentation

The most complete documentation will live on the Capgo docs portal. Until then, explore the TypeScript definitions (src/definitions.ts) and run the included example app for a tour of the API.

Compatibility

Plugin versionCapacitor compatibilityMaintained
v8.*.*v8.*.*✅
v7.*.*v7.*.*On demand
v6.*.*v6.*.*❌
v5.*.*v5.*.*❌

Note: The major version of this plugin follows the major version of Capacitor. Use the version that matches your Capacitor installation (e.g., plugin v8 for Capacitor 8). Only the latest major version is actively maintained.

Install

You can use our AI-Assisted Setup to install the plugin. Add the Capgo skills to your AI tool using the following command:

npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins

Then use the following prompt:

Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-nfc` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

npm install @capgo/capacitor-nfc
npx cap sync

Remember to add the required platform configuration:

  • Android: ensure your AndroidManifest.xml declares the android.permission.NFC permission.
  • iOS: add NFCReaderUsageDescription to your app Info.plist to explain why NFC access is needed.
  • iOS (iosSessionType: 'tag'): to use the tag session type you must also add the Near Field Communication Tag Reader Session Formats entitlement (com.apple.developer.nfc.readersession.formats) to your app's entitlements file and include the TAG format (and optionally NDEF). Without this entitlement the session will fail to start.

Usage

Checking NFC hardware support

Before attempting to use NFC features, you can check if the device has NFC hardware:

import { CapacitorNfc } from '@capgo/capacitor-nfc';

const { supported } = await CapacitorNfc.isSupported();
if (!supported) {
  console.warn('This device does not have NFC hardware');
  // Hide NFC features in your UI
} else {
  // Check if NFC is currently enabled
  const { status } = await CapacitorNfc.getStatus();
  if (status === 'NFC_DISABLED') {
    console.warn('NFC is disabled. Prompt user to enable it.');
    // Optionally show settings button
  }
}

Reading NDEF tags (default behavior)

import { CapacitorNfc } from '@capgo/capacitor-nfc';

await CapacitorNfc.startScanning({
  invalidateAfterFirstRead: false, // keep the session open so we can write later
  alertMessage: 'Hold a tag near the top of your device.',
});

const listener = await CapacitorNfc.addListener('nfcEvent', (event) => {
  console.info('Tag type:', event.type);
  console.info('First record:', event.tag?.ndefMessage?.[0]);
});

// Later, write a simple text record back to the tag
const encoder = new TextEncoder();
const langBytes = Array.from(encoder.encode('en'));
const textBytes = Array.from(encoder.encode('Hello Capgo'));
const payload = [langBytes.length & 0x3f, ...langBytes, ...textBytes];

await CapacitorNfc.write({
  allowFormat: true,
  records: [
    {
      tnf: 0x01,
      type: [0x54], // 'T'
      id: [],
      payload,
    },
  ],
});

await listener.remove();
await CapacitorNfc.stopScanning();

Reading raw tags (iOS) - Get UID from unformatted tags

import { CapacitorNfc } from '@capgo/capacitor-nfc';

// Use 'tag' session type to read raw (non-NDEF) tags
await CapacitorNfc.startScanning({
  iosSessionType: 'tag', // Enable raw tag reading on iOS
  alertMessage: 'Hold your card near the device',
});

const listener = await CapacitorNfc.addListener('nfcEvent', (event) => {
  console.info('Tag detected:', event.type); // 'tag' or 'ndef'
  
  // Read the UID (identifier) - works for both NDEF and raw tags
  if (event.tag?.id) {
    const uid = event.tag.id.map(byte => byte.toString(16).padStart(2, '0').toUpperCase()).join(':');
    console.info('Tag UID:', uid); // e.g., "04:A1:B2:C3:D4:E5:F6"
  }
  
  // If the tag has NDEF data, it will also be available
  if (event.tag?.ndefMessage) {
    console.info('NDEF records:', event.tag.ndefMessage);
  }
});

await listener.remove();
await CapacitorNfc.stopScanning();

Handling iOS session endings

Listen for nfcSessionEnd to distinguish a user cancellation from a session timeout or another Core NFC error. The event is available for both ndef and tag iOS sessions. A normal first-read completion does not emit this event.

const sessionEndListener = await CapacitorNfc.addListener('nfcSessionEnd', ({ reason }) => {
  if (reason === 'userCancelled') {
    return;
  }

  console.warn(reason === 'sessionTimeout' ? 'No tag detected. Try again.' : 'The NFC session failed.');
});

// Later, when the listener is no longer needed
await sessionEndListener.remove();

API

Public API surface for the Capacitor NFC plugin.

The interface intentionally mirrors the behaviour of the reference PhoneGap implementation to ease migration while embracing idiomatic Capacitor APIs.

startScanning(...)

startScanning(options?: StartScanningOptions | undefined) => Promise<void>

Starts listening for NFC tags.

ParamType
optionsStartScanningOptions

stopScanning()

stopScanning() => Promise<void>

Stops the ongoing NFC scanning session.


write(...)

write(options: WriteTagOptions) => Promise<void>

Writes the provided NDEF records to the last discovered tag.

ParamType
optionsWriteTagOptions

erase()

erase() => Promise<void>

Attempts to erase the last discovered tag by writing an empty NDEF message.


makeReadOnly()

makeReadOnly() => Promise<void>

Attempts to make the last discovered tag read-only.


transceive(...)

transceive(options: TransceiveOptions) => Promise<TransceiveResult>

Sends a raw command to the last discovered tag while it remains in the field.

On Android, uses NfcV or NfcA on the same tag as {@link CapacitorNfcPlugin.write}. On iOS, requires an active tag reader session (iosSessionType: 'tag') with invalidateAfterFirstRead: false, and uses ISO 15693 or MIFARE commands on the connected tag.

ParamType
optionsTransceiveOptions

Returns: Promise<TransceiveResult>


share(...)

share(options: ShareTagOptions) => Promise<void>

Shares an NDEF message with another device via peer-to-peer (Android only).

ParamType
optionsShareTagOptions

unshare()

unshare() => Promise<void>

Stops sharing previously provided NDEF message (Android only).


getStatus()

getStatus() => Promise<{ status: NfcStatus; }>

Returns the current NFC adapter status.

Returns: Promise<{ status: NfcStatus; }>


showSettings()

showSettings() => Promise<void>

Opens the system settings page where the user can enable NFC.


getPluginVersion()

getPluginVersion() => Promise<{ version: string; }>

Returns the version string baked into the native plugin.

Returns: Promise<{ version: string; }>


isSupported()

isSupported() => Promise<{ supported: boolean; }>

Checks whether the device has NFC hardware support.

Returns true if NFC hardware is present on the device, regardless of whether NFC is currently enabled or disabled. Returns false if the device does not have NFC hardware.

Use this method to determine if NFC features should be shown in your app's UI. To check if NFC is currently enabled, use getStatus().

Returns: Promise<{ supported: boolean; }>


addListener('nfcEvent', ...)

addListener(eventName: 'nfcEvent', listenerFunc: (event: NfcEvent) => void) => Promise<PluginListenerHandle>
ParamType
eventName'nfcEvent'
listenerFunc(event: NfcEvent) => void

Returns: Promise<PluginListenerHandle>


addListener('tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', ...)

addListener(eventName: 'tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', listenerFunc: (event: NfcEvent) => void) => Promise<PluginListenerHandle>
ParamType
eventName'tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered'
listenerFunc(event: NfcEvent) => void

Returns: Promise<PluginListenerHandle>


addListener('nfcStateChange', ...)

addListener(eventName: 'nfcStateChange', listenerFunc: (event: NfcStateChangeEvent) => void) => Promise<PluginListenerHandle>
ParamType
eventName'nfcStateChange'
listenerFunc(event: NfcStateChangeEvent) => void

Returns: Promise<PluginListenerHandle>


addListener('nfcSessionEnd', ...)

addListener(eventName: 'nfcSessionEnd', listenerFunc: (event: NfcSessionEndEvent) => void) => Promise<PluginListenerHandle>
ParamType
eventName'nfcSessionEnd'
listenerFunc(event: NfcSessionEndEvent) => void

Returns: Promise<PluginListenerHandle>


Interfaces

StartScanningOptions

Options controlling the behaviour of {@link CapacitorNfcPlugin.startScanning}.

PropTypeDescription
invalidateAfterFirstReadbooleaniOS-only: closes the NFC session automatically after the first successful tag read. Defaults to true.
alertMessagestringiOS-only: custom message displayed in the NFC system sheet while scanning.
iosSessionType'tag' | 'ndef'iOS-only: session type to use for NFC scanning. - 'ndef': Uses NFCNDEFReaderSession (default). Only detects NDEF-formatted tags. - 'tag': Uses NFCTagReaderSession. Detects both NDEF and non-NDEF tags (e.g., raw MIFARE tags). Allows reading UID from unformatted tags. Requires the Near Field Communication Tag Reader Session Formats entitlement in your app with the TAG format included. Without it the session will fail to start and the promise will reject with a NO_NFC error code. Defaults to 'ndef' for backward compatibility.
iosPollingOptionsNfcIosPollingOption[]iOS-only: polling options to use for NFC scanning. Defaults to ['iso14443', 'iso15693']. Apps that scan FeliCa tags can opt in to 'iso18092' after configuring the required FeliCa entitlement and system codes.
androidReaderModeFlagsnumberAndroid-only: raw flags passed to NfcAdapter.enableReaderMode. Defaults to enabling all tag types and Android's NDEF discovery so that detected tags remain available for writing and formatting.

WriteTagOptions

Options used when writing an NDEF message on the current tag.

PropTypeDescription
recordsNdefRecord[]Array of records that compose the NDEF message to be written.
allowFormatbooleanWhen true, the plugin attempts to format NDEF-formattable tags before writing. Defaults to true.

NdefRecord

JSON structure representing a single NDEF record.

Mirrors the data format returned by the legacy Cordova implementation and uses integer arrays instead of strings to preserve the original payload bytes.

PropTypeDescription
tnfnumberType Name Format identifier.
typenumber[]Type field expressed as an array of byte values.
idnumber[]Record identifier expressed as an array of byte values.
payloadnumber[]Raw payload expressed as an array of byte values.

TransceiveResult

Result of a successful {@link CapacitorNfcPlugin.transceive} call.

PropTypeDescription
responsenumber[]Raw response frame from the tag (ISO 15693 responses include the response flags as the first byte).

TransceiveOptions

Options for sending a raw command to the current tag.

PropTypeDescription
datanumber[]Raw request frame without CRC. For ISO 15693 (nfcV), the first byte is the request flags and the second byte is the command code, followed by any command parameters. The response includes the response flags as the first byte.
techTransceiveTechWhich technology to use. Defaults to the technology detected for the current tag.
timeoutnumberAndroid only: transceive timeout in milliseconds for NFC-A (nfcA). Ignored for ISO 15693 (nfcV).

ShareTagOptions

Options used when sharing an NDEF message with another device using Android Beam / P2P mode.

PropType
recordsNdefRecord[]

PluginListenerHandle

PropType
remove() => Promise<void>

NfcEvent

Generic NFC discovery event dispatched by the plugin.

PropType
typeNfcEventType
tagNfcTag

NfcTag

Representation of the full tag information returned by the native layers.

Supports standard NFC Forum tags as well as MIFARE Ultralight cards (including EV1 and NTAG variants). NDEF data is automatically extracted from MIFARE Ultralight tags when available.

PropTypeDescription
idnumber[]Raw identifier bytes for the tag.
techTypesstring[]List of Android tech strings (e.g. android.nfc.tech.Ndef).
typestring | nullHuman readable tag type when available (e.g. NFC Forum Type 2, MIFARE Ultralight).
maxSizenumber | nullMaximum writable size in bytes for tags that expose NDEF information.
isWritableboolean | nullIndicates whether the tag can be written to.
canMakeReadOnlyboolean | nullIndicates whether the tag can be permanently locked.
ndefMessageNdefRecord[] | nullArray of NDEF records discovered on the tag.

NfcStateChangeEvent

Event emitted whenever the NFC adapter availability changes.

PropType
statusNfcStatus
enabledboolean

NfcSessionEndEvent

Event emitted when an iOS NFC reader session ends.

This event is not emitted when a session closes normally after its first successful read.

PropType
reason'userCancelled' | 'sessionTimeout' | 'invalidated'

Type Aliases

NfcIosPollingOption

iOS-specific polling options for NFC scanning sessions. These options determine the type of tags that a reader session should detect during a polling sequence.

  • 'iso14443': Polls for ISO 14443 tags
  • 'iso15693': Polls for ISO 15693 tags
  • 'iso18092': Polls for ISO 18092 tags
  • 'pace': Polls for PACE tags (available on iOS 16 and later)

'iso14443' | 'iso15693' | 'iso18092' | 'pace'

TransceiveTech

NFC technology used for {@link CapacitorNfcPlugin.transceive}.

  • nfcV: ISO 15693 (for example ST25DV).
  • nfcA: NFC-A / MIFARE (for example NTAG I2C plus).

'nfcV' | 'nfcA'

NfcStatus

Possible NFC adapter states returned by {@link CapacitorNfcPlugin.getStatus}.

Matches the constants provided by the original PhoneGap NFC plugin for compatibility with existing applications.

'NFC_OK' | 'NO_NFC' | 'NFC_DISABLED' | 'NDEF_PUSH_DISABLED'

NfcEventType

Event type describing the kind of NFC discovery that happened.

  • tag: A generic NFC tag (no NDEF payload).
  • ndef: A tag exposing an NDEF payload.
  • ndef-mime: An NDEF tag that matched one of the MIME type filters.
  • ndef-formatable: A tag that can be formatted to NDEF.

'tag' | 'ndef' | 'ndef-mime' | 'ndef-formatable'

版本与发布记录

@capgo/capacitor-nfc 共发布 64 个版本,首次发布于 2025/10/27;过去 12 个月发布了 56 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
8.3.7latest2026/11/09今天
8.3.62026/11/026 天前
8.3.52026/10/2613 天前
8.3.42026/10/1920 天前
8.3.32026/10/1525 天前
8.3.22026/10/1327 天前

关于 @capgo/capacitor-nfc 的常见问题

@capgo/capacitor-nfc 是什么?

Native NFC tag discovery, reading and writing for Capacitor apps on iOS and Android.

如何安装 @capgo/capacitor-nfc?

在项目目录运行 npm install @capgo/capacitor-nfc,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@capacitor/core(>=8.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@capgo/capacitor-nfc 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@capgo/capacitor-nfc 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@capgo/capacitor-nfc 可以商用吗?

@capgo/capacitor-nfc 使用 MPL-2.0 许可。弱 Copyleft:可以商用,也可以和闭源代码一起使用;但如果分发时修改了 MPL 授权的文件,这些文件的修改需以 MPL 开源。以上为概括,不构成法律意见,请以许可原文为准。

@capgo/capacitor-nfc 的下载量有多少?

根据 npm 官方下载统计,@capgo/capacitor-nfc 在 2026/10/09 – 2026/11/07 这 30 天内被下载 117,863 次,日均约 3,929 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@capgo/capacitor-nfc 还在维护吗?

最新版本 8.3.7 发布于 2026/11/09(今天);至今共发布 64 个版本,其中过去 12 个月发布了 56 个;首次发布于 2025/10/27。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。