https://github.com/Cap-go/capacitor-nfc
Capacitor plugin allows you to read and write NFC tags. You can also beam to, and receive from, other NFC enabled devices.
https://github.com/Cap-go/capacitor-nfc
Last synced: about 1 month ago
JSON representation
Capacitor plugin allows you to read and write NFC tags. You can also beam to, and receive from, other NFC enabled devices.
- Host: GitHub
- URL: https://github.com/Cap-go/capacitor-nfc
- Owner: Cap-go
- License: mpl-2.0
- Created: 2025-10-27T03:47:25.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-01-31T23:02:48.000Z (about 1 month ago)
- Last Synced: 2026-02-01T10:57:25.822Z (about 1 month ago)
- Language: Java
- Size: 574 KB
- Stars: 10
- Watchers: 0
- Forks: 1
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome-capacitor - NFC - Native NFC tag discovery, reading and writing for iOS and Android. ([Capgo plugins](https://capgo.app/) / Communication & Messaging)
README
Native NFC tag detection, reading, and writing for Capacitor apps on iOS and Android.
Modern Capacitor port of the battle-tested [phonegap-nfc](https://github.com/chariotsolutions/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 version | Capacitor compatibility | Maintained |
| -------------- | ----------------------- | ---------- |
| 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
```bash
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.
## Usage
```ts
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();
```
## API
* [`startScanning(...)`](#startscanning)
* [`stopScanning()`](#stopscanning)
* [`write(...)`](#write)
* [`erase()`](#erase)
* [`makeReadOnly()`](#makereadonly)
* [`share(...)`](#share)
* [`unshare()`](#unshare)
* [`getStatus()`](#getstatus)
* [`showSettings()`](#showsettings)
* [`getPluginVersion()`](#getpluginversion)
* [`addListener('nfcEvent', ...)`](#addlistenernfcevent-)
* [`addListener('tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', ...)`](#addlistenertagdiscovered--ndefdiscovered--ndefmimediscovered--ndefformatablediscovered-)
* [`addListener('nfcStateChange', ...)`](#addlistenernfcstatechange-)
* [Interfaces](#interfaces)
* [Type Aliases](#type-aliases)
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(...)
```typescript
startScanning(options?: StartScanningOptions | undefined) => Promise
```
Starts listening for NFC tags.
| Param | Type |
| ------------- | --------------------------------------------------------------------- |
| **`options`** | StartScanningOptions |
--------------------
### stopScanning()
```typescript
stopScanning() => Promise
```
Stops the ongoing NFC scanning session.
--------------------
### write(...)
```typescript
write(options: WriteTagOptions) => Promise
```
Writes the provided NDEF records to the last discovered tag.
| Param | Type |
| ------------- | ----------------------------------------------------------- |
| **`options`** | WriteTagOptions |
--------------------
### erase()
```typescript
erase() => Promise
```
Attempts to erase the last discovered tag by writing an empty NDEF message.
--------------------
### makeReadOnly()
```typescript
makeReadOnly() => Promise
```
Attempts to make the last discovered tag read-only.
--------------------
### share(...)
```typescript
share(options: ShareTagOptions) => Promise
```
Shares an NDEF message with another device via peer-to-peer (Android only).
| Param | Type |
| ------------- | ----------------------------------------------------------- |
| **`options`** | ShareTagOptions |
--------------------
### unshare()
```typescript
unshare() => Promise
```
Stops sharing previously provided NDEF message (Android only).
--------------------
### getStatus()
```typescript
getStatus() => Promise<{ status: NfcStatus; }>
```
Returns the current NFC adapter status.
**Returns:** Promise<{ status: NfcStatus; }>
--------------------
### showSettings()
```typescript
showSettings() => Promise
```
Opens the system settings page where the user can enable NFC.
--------------------
### getPluginVersion()
```typescript
getPluginVersion() => Promise<{ version: string; }>
```
Returns the version string baked into the native plugin.
**Returns:** Promise<{ version: string; }>
--------------------
### addListener('nfcEvent', ...)
```typescript
addListener(eventName: 'nfcEvent', listenerFunc: (event: NfcEvent) => void) => Promise
```
| Param | Type |
| ------------------ | ----------------------------------------------------------------- |
| **`eventName`** | 'nfcEvent' |
| **`listenerFunc`** | (event: NfcEvent) => void |
**Returns:** Promise<PluginListenerHandle>
--------------------
### addListener('tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', ...)
```typescript
addListener(eventName: 'tagDiscovered' | 'ndefDiscovered' | 'ndefMimeDiscovered' | 'ndefFormatableDiscovered', listenerFunc: (event: NfcEvent) => void) => Promise
```
| Param | Type |
| ------------------ | ------------------------------------------------------------------------------------------------------ |
| **`eventName`** | 'tagDiscovered' \| 'ndefDiscovered' \| 'ndefMimeDiscovered' \| 'ndefFormatableDiscovered' |
| **`listenerFunc`** | (event: NfcEvent) => void |
**Returns:** Promise<PluginListenerHandle>
--------------------
### addListener('nfcStateChange', ...)
```typescript
addListener(eventName: 'nfcStateChange', listenerFunc: (event: NfcStateChangeEvent) => void) => Promise
```
| Param | Type |
| ------------------ | --------------------------------------------------------------------------------------- |
| **`eventName`** | 'nfcStateChange' |
| **`listenerFunc`** | (event: NfcStateChangeEvent) => void |
**Returns:** Promise<PluginListenerHandle>
--------------------
### Interfaces
#### StartScanningOptions
Options controlling the behaviour of {@link CapacitorNfcPlugin.startScanning}.
| Prop | Type | Description |
| ------------------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **`invalidateAfterFirstRead`** | boolean | iOS-only: closes the NFC session automatically after the first successful tag read. Defaults to `true`. |
| **`alertMessage`** | string | iOS-only: custom message displayed in the NFC system sheet while scanning. |
| **`androidReaderModeFlags`** | number | Android-only: raw flags passed to `NfcAdapter.enableReaderMode`. Defaults to enabling all tag types with skipping NDEF checks. |
#### WriteTagOptions
Options used when writing an NDEF message on the current tag.
| Prop | Type | Description |
| ----------------- | ------------------------- | ---------------------------------------------------------------------------------------------------- |
| **`records`** | NdefRecord[] | Array of records that compose the NDEF message to be written. |
| **`allowFormat`** | boolean | When `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.
| Prop | Type | Description |
| ------------- | --------------------- | ------------------------------------------------------- |
| **`tnf`** | number | Type Name Format identifier. |
| **`type`** | number[] | Type field expressed as an array of byte values. |
| **`id`** | number[] | Record identifier expressed as an array of byte values. |
| **`payload`** | number[] | Raw payload expressed as an array of byte values. |
#### ShareTagOptions
Options used when sharing an NDEF message with another device using Android Beam / P2P mode.
| Prop | Type |
| ------------- | ------------------------- |
| **`records`** | NdefRecord[] |
#### PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| **`remove`** | () => Promise<void> |
#### NfcEvent
Generic NFC discovery event dispatched by the plugin.
| Prop | Type |
| ---------- | ----------------------------------------------------- |
| **`type`** | NfcEventType |
| **`tag`** | NfcTag |
#### 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.
| Prop | Type | Description |
| --------------------- | --------------------------------- | -------------------------------------------------------------------------------------- |
| **`id`** | number[] | Raw identifier bytes for the tag. |
| **`techTypes`** | string[] | List of Android tech strings (e.g. `android.nfc.tech.Ndef`). |
| **`type`** | string \| null | Human readable tag type when available (e.g. `NFC Forum Type 2`, `MIFARE Ultralight`). |
| **`maxSize`** | number \| null | Maximum writable size in bytes for tags that expose NDEF information. |
| **`isWritable`** | boolean \| null | Indicates whether the tag can be written to. |
| **`canMakeReadOnly`** | boolean \| null | Indicates whether the tag can be permanently locked. |
| **`ndefMessage`** | NdefRecord[] \| null | Array of NDEF records discovered on the tag. |
#### NfcStateChangeEvent
Event emitted whenever the NFC adapter availability changes.
| Prop | Type |
| ------------- | ----------------------------------------------- |
| **`status`** | NfcStatus |
| **`enabled`** | boolean |
### Type Aliases
#### 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'
