Easy reading and writing NFC tags and cards with bindings over PC/SC to access Smart Cards
npm install nfc-pcsclite

!GitHub contributors
!GitHub Issues or Pull Requests
!GitHub License
> Cross-platform NFC library for Node.js
> Read and write NFC tags and smart cards using built-in PC/SC bindings.
> Works on Linux, macOS, and Windows.
---
- Overview
- Installation
- Requirements
- Node.js
- Build tools
- PC/SC API
- Install package
- NFC Tag Handling Flow
- Basic Usage
- Alternative Usage (Manual Processing)
- Reading & Writing Data
- FAQ
- Can I use it in Electron?
- Can I use it in Angular + Electron?
- Do I need Babel?
- Supported Node.js versions
- Can I read NDEF tags?
- React Native support?
- Common Issues
- Transaction failed using CONNECT_MODE_DIRECT
- Authentication Error after Multiple Writes (MIFARE Classic)
- Reading Type 4 tags (Elsys sensors)
- Disclaimer
- License
nfc-pcsclite provides a low-level Node.js interface for NFC operations using PC/SC bindings.
It supports automatic card detection, UID reading, and communication with Android HCE devices.
✅ Supports card UID auto-reading
✅ Works with ACR122 USB reader and other PC/SC-compliant devices
✅ Includes native pcsclite bindings
> ⚠️ If card detection fails, check the Alternative Usage section.
---
#### Node.js
Compatible with Node.js 18 or newer.
#### Build tools
This package includes native bindings built with node-gyp.
Ensure you have a C/C++ toolchain installed for your OS.
See node-gyp Installation Guide.
#### PC/SC API
- macOS / Windows: Already included.
- Linux / UNIX: Install manually:
``bash`
apt-get install libpcsclite1 libpcsclite-dev pcscd
#### Install package
`bashUsing npm
npm install nfc-pcsclite
---
NFC Tag Handling Flow
When a tag is detected, the following occurs:
1. Detects the card standard (
TAG_ISO_14443_3 or TAG_ISO_14443_4);
2. Connects to the card;
3. Depending on autoProcessing:
- true (default): automatically retrieves UID or APDU data; or
- false: triggers card event only, letting you handle transmission manually;
4. You can then read, write, or send custom commands.---
Basic Usage
`js
import { NFC } from 'nfc-pcsc';const nfc = new NFC(); // optional: pass a logger (e.g. Pino, Winston)
nfc.on('reader', reader => {
console.log(
${reader.reader.name} device attached); reader.on('card', card => {
console.log(
${reader.reader.name} card detected, card);
}); reader.on('card.off', card => {
console.log(
${reader.reader.name} card removed, card);
}); reader.on('error', err => {
console.error(
${reader.reader.name} error, err);
}); reader.on('end', () => {
console.log(
${reader.reader.name} device removed);
});
});nfc.on('error', err => {
console.error('An error occurred', err);
});
`---
Alternative Usage (Manual Processing)
`js
import { NFC } from 'nfc-pcsc';const nfc = new NFC();
nfc.on('reader', reader => {
reader.autoProcessing = false;
console.log(
${reader.reader.name} device attached); reader.on('card', card => {
console.log(
${reader.reader.name} card inserted, card); // Send custom APDU commands using reader.transmit()
});
});
`---
Reading & Writing Data
Example with MIFARE Ultralight tag:
`js
reader.on('card', async card => {
try {
const data = await reader.read(4, 12);
console.log('Data read:', data.toString());
} catch (err) {
console.error('Error reading data', err);
} try {
const text = 'Bright minds build code';
const buffer = Buffer.alloc(12, 0);
buffer.write(text);
await reader.write(4, buffer);
console.log('Data written');
} catch (err) {
console.error('Error writing data', err);
}
});
`---
FAQ
$3
Yes. It works with Electron and other Node.js environments that support native modules.
See Electron’s guide on native modules.
$3
Yes. You’ll need to update your
package.json and webpack.config.js per this issue comment.$3
No. The library is already transpiled to support Node.js 18+.
$3
It supports from the version
18.x to the latest 25.x, including the current LTS on 22.x. Node.js uses the convention of having the even-numbered versions as stable releases and odd-numbered versions having experimental features, but even and odd-numbered version numbers are basically backwards compatible.Ref: Official Node.js Release Plan
$3
Yes. Use
reader.read() and parse the raw bytes with TapTrack/NdefJS.$3
No.
nfc-pcsclite depends on Node.js native bindings and PC/SC APIs, unavailable in mobile runtimes.---
Common Issues
$3
See explanation.
$3
See instructions.
$3
Set
readClass to 0x00 in:`js
reader.read(blockNumber, length, blockSize, packetSize, 0x00);
``See discussion.
---
This library revives maintenance over an abandoned project. For a high-level API, see nfc-pcsc.
---
Released under the MIT License.