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 🙏

© 2025 – Pkg Stats / Ryan Hefner

mifare-reader-js

v1.0.3

Published

A TypeScript library for interfacing with MIFARE card readers via serial port communication

Downloads

36

Readme

mifare-reader-js

A TypeScript library for interfacing with MIFARE card readers via serial port communication. This library provides a clean, promise-based API for communicating with MIFARE Classic RFID cards through serial port connections, commonly used with devices like the CR522AU or similar card readers.

Features

  • Multi-Format Support: Works with both CommonJS and ES Modules
  • Full TypeScript Support: Complete type definitions for all APIs
  • Serial Communication: Robust serial port communication using serialport library
  • Retry Logic: Built-in initialization retry mechanism (up to 20 attempts by default)
  • Timeout Handling: Configurable command timeouts prevent hanging operations
  • Hardware Integration:
    • LED control (4 color states: GREEN, RED, YELLOW, OFF)
    • Audio feedback (beep functionality)
    • Card detection and reading
    • RF authentication with key modes (A/B)

Tested Devices

This library has been tested and confirmed to work with the following MIFARE card reader devices:

| Brand | Model | Made By | Baudrate | Notes | |-------|-------|---------|----------|-------| | NfcPass | CR522AU-V7| ChinaReader | 19200 | N/A |

Contributing: If you've successfully tested this library with a specific reader model, please consider contributing by adding the device information to this table. Include the brand name, model number, manufacturer, and working baudrate.

Installation

Prerequisites

  • Node.js >= 14.0.0
  • A MIFARE card reader connected via serial port
  • Compatible driver for the reader device installed
    • Windows: After plugging in the device, it should be recognized in Device Manager under "Ports (COM & LPT)" section (e.g., COM3, COM5)
    • Linux: The device should appear as /dev/ttyUSB0, /dev/ttyACM0, or similar. Check with ls -la /dev/tty*
    • macOS: The device should appear as /dev/cu.usbserial-* or similar. Check with ls -la /dev/tty.* /dev/cu.*
    • If the device is not recognized, install the appropriate USB-to-Serial driver (e.g., CH340, CP2102, FTDI drivers)

Install from npm

npm install mifare-reader-js

Install from Local Directory

npm install /path/to/mifare-reader-js

Install from Package File

npm pack
npm install ./mifare-reader-js-1.0.0.tgz

Quick Start

Note: If the device does not respond during initialization, try changing the baudrate. Common values are 9600, 19200, 57600, or 115200. Different reader models may use different default baudrates.

TypeScript Example

import { MifareReader, COLORS } from 'mifare-reader-js';

const reader = new MifareReader();

async function readCard() {
  try {
    // Initialize reader on COM3 at 19200 baud
    await reader.initialize('COM3', 19200);

    // Detect a card
    const cardId = await reader.selectCard();

    if (cardId) {
      console.log('Card detected:', cardId);

      // Visual feedback: turn LED green
      await reader.changeLedColor(COLORS.GREEN);

      // Read card data with default MIFARE key
      const data = await reader.readCard();
      console.log('Card data:', data);

      // Audio feedback
      await reader.beep();
    } else {
      console.log('No card detected');
    }
  } catch (error) {
    console.error('Error:', error);
  } finally {
    reader.closePort();
  }
}

readCard();

JavaScript (CommonJS) Example

const { MifareReader, COLORS } = require('mifare-reader-js');

const reader = new MifareReader();

async function main() {
  try {
    await reader.initialize('COM3', 19200);
    const cardId = await reader.selectCard();

    if (cardId) {
      await reader.changeLedColor(COLORS.GREEN);
      await reader.beep();
      const data = await reader.readCard();
      console.log('Card data:', data);
    }
  } finally {
    reader.closePort();
  }
}

main();

API Reference

MifareReader Class

Constructor

const reader = new MifareReader();

Methods

initialize(portNo: string, baudRate: 9600 | 19200 | 57600 | 115200, maxRetries?: number): Promise<boolean>

Initializes connection to the card reader device.

Parameters:

  • portNo - Serial port name
    • Windows: 'COM1', 'COM3', etc.
    • Linux/Mac: '/dev/ttyUSB0', '/dev/ttyACM0', etc.
  • baudRate - Communication speed (default: 19200)
    • Supported values: 9600, 19200, 57600, 115200
  • maxRetries - Maximum retry attempts (default: 20)

Returns: Promise resolving to true if successful, false otherwise

Example:

await reader.initialize('COM3', 19200);

selectCard(): Promise<string | null>

Attempts to detect and select a card in the reader.

Returns: Promise resolving to:

  • Card ID as a hex string if card is detected
  • null if no card is detected

Example:

const cardId = await reader.selectCard();
if (cardId) {
  console.log('Card ID:', cardId);
}

readCard(key?: string | Buffer, keyMode?: 'A' | 'B'): Promise<string>

Reads data from the selected card. Requires successful authentication first.

Parameters:

  • key - 6-byte authentication key (hex string or Buffer)
    • Default: 'ffffffffffff' (default MIFARE key)
    • Must be 6 bytes/12 hex characters
  • keyMode - Authentication key mode
    • 'A' (default) or 'B'

Returns: Promise resolving to card data as a hex string (16 bytes)

Note: This method internally calls authen() for authentication.

Example:

// Using default key
const data = await reader.readCard();

// Using custom key with mode B
const data = await reader.readCard('123456789abc', 'B');

authen(key?: string | Buffer, keyMode?: 'A' | 'B'): Promise<boolean>

Authenticates with the card using the specified key. Must be called before readCard().

Parameters:

  • key - 6-byte authentication key (default: 'ffffffffffff')
  • keyMode - Key mode 'A' or 'B' (default: 'A')

Returns: Promise resolving to true if authentication successful, false otherwise

Example:

const authenticated = await reader.authen('ffffffffffff', 'A');
if (authenticated) {
  const data = await reader.readCard();
}

changeLedColor(color: 'GREEN' | 'RED' | 'YELLOW' | 'OFF'): Promise<boolean>

Controls the reader's LED indicator.

Parameters:

  • color - LED color state
    • 'GREEN' - Green LED
    • 'RED' - Red LED
    • 'YELLOW' - Yellow LED
    • 'OFF' - Turn off LED

Returns: Promise resolving to true if successful, false otherwise

Example:

import { COLORS } from 'mifare-reader-js';

await reader.changeLedColor(COLORS.GREEN);

beep(): Promise<boolean>

Triggers the reader's audio indicator.

Returns: Promise resolving to true if successful, false otherwise

Example:

await reader.beep();

closePort(): void

Closes the serial port connection. Should be called for proper cleanup.

Example:

reader.closePort();

Constants

COLORS

import { COLORS } from 'mifare-reader-js';

console.log(COLORS.GREEN);   // "GREEN"
console.log(COLORS.RED);     // "RED"
console.log(COLORS.YELLOW);  // "YELLOW"
console.log(COLORS.OFF);     // "OFF"

KEY_MODE

import { KEY_MODE } from 'mifare-reader-js';

console.log(KEY_MODE.A);  // Buffer [0x61]
console.log(KEY_MODE.B);  // Buffer [0x60]

Port Configuration

To find your serial port:

Windows

  • Check Device Manager → Ports (COM & LPT)
  • Common ports: COM1, COM3, COM5
  • Use node -e "require('serialport').SerialPort.list().then(ports => console.log(ports))"

Linux

# List all serial ports
ls -la /dev/tty*

# Common ports: /dev/ttyUSB0, /dev/ttyACM0
dmesg | grep tty  # Check kernel messages

macOS

# List all serial ports
ls -la /dev/tty.* /dev/cu.*

# Common ports: /dev/cu.usbserial-*, /dev/cu.SLAB_USBtoUART

Development Guide

Prerequisites

  • Node.js >= 14.0.0
  • npm or yarn
  • TypeScript knowledge (recommended)

Setup

  1. Clone the repository:
git clone <repository-url>
cd mifare-reader-js
  1. Install dependencies:
npm install
  1. Build the project:
npm run build

Project Structure

mifare-reader-js/
├── src/
│   ├── core/
│   │   └── MifareReader/
│   │       └── index.ts              # Main MifareReader class
│   ├── types/
│   │   └── types.ts                  # Type definitions and constants
│   ├── example-test-*.ts             # Usage examples
│   └── index.ts                      # Main entry point
├── dist/
│   ├── cjs/                          # CommonJS compiled output
│   └── esm/                          # ES Module compiled output
├── scripts/
│   └── create-esm-package.js         # ESM build helper
├── package.json
├── tsconfig.json                     # TypeScript config (CommonJS)
├── tsconfig.esm.json                 # TypeScript config (ES Modules)
└── README.md

Build Scripts

# Build both CommonJS and ES Module formats
npm run build

# Build only CommonJS
npm run build:cjs

# Build only ES Module
npm run build:esm

# Development mode (ts-node)
npm run dev

Compilation Details

CommonJS Build

  • Configuration: tsconfig.json
  • Output: dist/cjs/
  • Target: ES2020
  • Module: CommonJS

ES Module Build

  • Configuration: tsconfig.esm.json
  • Output: dist/esm/
  • Target: ES2020
  • Module: ES2020
  • Creates package.json with "type": "module"

TypeScript Configuration

The project uses strict TypeScript settings:

  • Strict mode enabled
  • Source maps included
  • Declaration files (.d.ts) generated

Example Files

Run the example files to test functionality:

# Using ts-node directly
npx ts-node src/example-test-readcard.ts

# Or with npm script
npm run dev src/example-test-readcard.ts

Available examples:

  • example-test-readcard.ts - Card detection and data reading
  • example-test-led.ts - LED color control
  • example-test-beep.ts - Audio feedback
  • example-test-port.ts - Basic port connectivity
  • example-test-select-card.ts - Card selection/detection
  • example-test-mixing.ts - Combined operations

Note: Update the port and baud rate in examples before running.

Making Changes

  1. Modify source files in src/
  2. Run npm run build to compile
  3. Test changes with example files
  4. Check compiled output in dist/ directory

Adding New Features

  1. Add types to src/types/types.ts
  2. Implement functionality in src/core/MifareReader/index.ts
  3. Export new types/methods in src/index.ts
  4. Create example file to demonstrate usage
  5. Build and test with npm run build

Publishing to npm

  1. Create npm account at https://www.npmjs.com
  2. Login locally:
npm login
  1. Update package.json metadata:

    • Update version in version field
    • Add your username to author field
    • Update repository.url, bugs.url, and homepage
  2. Publish:

npm publish

The prepublishOnly script automatically builds before publishing.


Troubleshooting

Port Not Found

  • Verify the port name matches your system
  • Check Device Manager (Windows) or ls /dev/tty* (Linux/Mac)
  • Ensure the reader is properly connected and recognized by the OS

Connection Fails

  • Try different baud rates (9600, 19200, 57600, 115200)
  • Verify the reader is powered and properly connected
  • Check for driver issues (Windows: USB drivers may need installation)
  • Increase maxRetries parameter

Card Not Detected

  • Ensure card is properly positioned in the reader
  • Try moving the card slightly to find the sweet spot
  • Check if the reader's LED is functioning
  • Verify card is a MIFARE Classic card

Authentication Fails

  • Verify the key is correct (should be 6 bytes/12 hex characters)
  • Try the default key 'ffffffffffff'
  • Ensure key mode ('A' or 'B') matches the card configuration
  • Check card is still properly positioned

Module Import Issues

  • For CommonJS: const { MifareReader } = require('mifare-reader-js');
  • For ES Modules: import { MifareReader } from 'mifare-reader-js';
  • Ensure build output exists: npm run build

Changelog

See CHANGELOG.md for a detailed history of changes and version updates.

Latest Version (1.0.3)

  • Fixed: Select card ID issue - selectCard() now returns correct card ID

License

ISC


Resources


Contributing

Contributions are welcome! Please ensure:

  • Code follows TypeScript strict mode
  • Changes are properly tested
  • Documentation is updated
  • Build passes without errors: npm run build