Introduction
Recently, I worked on integrating an RFID reader into a React application. Although I’ve integrated APIs and third-party libraries many times before, working with hardware devices was a completely different experience. It gave me an opportunity to understand how browsers communicate with physical devices and how browser APIs can be used beyond traditional web development.
Like many developers, my first assumption was that the hardware team would provide a private npm package that I could install and use directly.
I expected the integration to be as simple as:
import { connectRFID, scanTag } from “@company/rfid-sdk”;
The plan seemed straightforward:
Install the package
Import the required functions
Connect the device
Start scanning RFID tags
However, the actual implementation was very different.
Instead of an npm package, I received a standalone SDK built with HTML, CSS, and JavaScript. At first, I wasn’t sure how I was supposed to integrate an entire web application into an existing React project.
Rather than trying to embed the SDK into my application, I decided to understand how it worked internally. That decision completely changed my approach.
Understanding the SDK for RFID
After exploring the SDK, I found that it wasn’t a React library or a complex framework. It was simply a collection of HTML, CSS, and JavaScript files that communicated with the RFID reader.
As I read through the source code, one thing became clear: the SDK wasn’t performing any hidden logic. It was simply acting as a wrapper around the browser’s Web Serial API.
Its overall workflow was quite simple:
Open a serial connection
Send commands to the RFID reader
Read the device response
Extract the RFID tag information
Return the result to the application
Once I understood this flow, I realized there was no need to integrate the entire SDK. Instead, I could implement only the functionality my application required while keeping everything inside the React codebase.
This approach made the application cleaner, easier to maintain, and much more flexible.
Designing the Solution to Connect with RFID
To keep the implementation organised, I separated the hardware communication into reusable service functions rather than placing the logic inside React components.
The communication flow looked like this:
Connect Device
↓
Open Serial Port
↓
Send Command
↓
Read Response
↓
Extract EPC
↓
Return RFID Tags
Keeping each responsibility separate made the code easier to test, debug, and extend in the future.
Connecting to the RFID Reader
The first step was establishing communication with the RFID reader.
Using the browser’s Web Serial API, the application requests permission to access a serial device:
navigator.serial.requestPort();
After the user selects the appropriate device, the serial connection is opened with the required baud rate.
await port.open({
baudRate: 38400,
});
To avoid duplicating connection logic across components, I created reusable helper functions such as:
connectRFID()
disconnectRFID()
isRFIDConnected()
getConnectedPort()
Encapsulating this logic in a dedicated service kept the UI clean and made the connection lifecycle much easier to manage.
Sending Commands to the RFID Reader
Once the connection is established, the application needs to communicate with the RFID reader by sending commands.
To simplify this process, I created a reusable helper:
sendCommand(command)
This function is responsible for converting commands into byte arrays, writing them to the serial port, and safely releasing the writer once the operation is complete.
Having a single function handle all outgoing communication keeps the implementation consistent and makes future command additions straightforward.
Reading RFID Device Responses
Reading data from the RFID reader was one of the most interesting parts of the project.
Unlike a traditional REST API request, the RFID reader continuously streams serial data. This means the application must listen for incoming responses without blocking the user interface.
To avoid waiting indefinitely, I implemented a timeout using Promise.race(). The application waits for whichever occurs first:
A response from the RFID reader
A timeout
This approach keeps the application responsive while ensuring that incoming RFID data is processed efficiently.
Extracting the EPC from RFID
The RFID reader returns more than just the RFID tag. Each response includes protocol information, headers, footers, and additional metadata.
For example:
AAAAA300833B2DDD901400000000BBBB
Since the application only requires the Electronic Product Code (EPC), I created a helper function:
extractEPC(response)
This function removes the unnecessary protocol information and returns only the EPC value.
By isolating this logic, the rest of the application remains independent of the device’s communication protocol.
Handling Duplicate Tags
During testing, I noticed that the RFID reader often detected the same tag multiple times within a short interval.
Processing duplicate values would create unnecessary work for the application, so I used JavaScript’s Set to ensure that each scan returned only unique RFID tags.
new Set(tags)
This small improvement significantly reduced redundant processing and simplified downstream logic.
Continuous Scanning the Tags
One of the project requirements was continuous scanning.
Instead of performing a single scan, the application needed to keep reading RFID tags until the user manually stopped the process.
To support this, I implemented two methods:
startContinuousScan()
stopContinuousScan()
The scanning loop repeatedly performs the following steps:
Send the scan command
Read the device response
Extract the EPC value
Return the detected tag to the React component
Repeat until scanning is stopped
This approach works well for inventory management, warehouse operations, and asset tracking scenarios where real-time scanning is essential.
Overall Architecture
After separating responsibilities, the final architecture became much simpler.
React Components
│
▼
RFID Service Layer
│
▼
Web Serial API
│
▼
RFID Reader
The React components focus solely on the user interface, while the service layer handles all communication with the hardware.
This separation makes the codebase easier to understand and simplifies future enhancements.
Why This Approach Worked Well
Building a dedicated RFID service instead of integrating the complete SDK provided several advantages:
A cleaner and more maintainable architecture
Better separation of concerns
Reusable communication logic
Easier testing and debugging
Simpler future enhancements
No unnecessary SDK files inside the React project
Most importantly, the solution fits naturally into any React application without introducing additional complexity.
Key Takeaways
This project was about much more than connecting an RFID reader.
It reinforced several engineering practices that apply to many software projects:
Take time to understand how an SDK works before integrating it.
Focus on the underlying problem rather than blindly using provided libraries.
Keep hardware communication separate from UI logic.
Build reusable service layers whenever possible.
Explore browser capabilities such as the Web Serial API.
Treat SDKs as learning resources rather than black boxes.
These lessons have influenced how I approach integrations today.
Final Thoughts
When I first received the SDK, I expected a plug-and-play npm package. Instead, I was given a standalone HTML, CSS, and JavaScript application.
Although it seemed challenging at first, taking the time to understand the SDK proved to be the right decision. Once I realized it was simply using the browser’s Web Serial API, I was able to build a solution tailored to my application’s architecture instead of forcing the SDK into my project.
The end result was a lightweight, reusable RFID service that was easier to maintain, easier to extend, and fully integrated into the React application.
This experience reminded me that the best solution isn’t always the one that’s provided. Sometimes, investing time to understand the underlying technology leads to a cleaner and more scalable implementation.
If you’re integrating an RFID device into a React application and receive a similar SDK, I’d encourage you to explore how it works internally before integrating it. Understanding the communication flow can help you build a solution that’s better aligned with your application’s architecture and easier to maintain in the long run.
Happy Coding!
Technologies Used
React.js
TypeScript
Web Serial API
JavaScript (ES6+)
RFID Reader SDK
The post Integrating an RFID Reader into a React Application Using the Web Serial API appeared first on Spritle software.
