Storage Tags is a local browser-based UHF RFID inventory system. It is designed for the Scenario B architecture: the RFID reader is connected to the operator device, the browser captures EPC values, and the local backend stores normalized reads in SQLite.
- Registers RFID EPC tags and associates them with inventory items.
- Runs inventory sessions for boxes, shelves, or containers.
- Accepts browser HID keyboard RFID input as the first MVP reader mode.
- Deduplicates repeated reads per inventory session.
- Shows known items, unknown tags, read counts, and confidence labels.
- Lets operators register unknown tags, mark them as external, or ignore them.
- Saves browser station settings for RFID input devices.
- Creates local SQLite backups.
- Loads demo data for testing without a physical RFID reader.
- Exports saved session results as CSV.
The data path is:
RFID Reader -> Browser -> Fastify API -> SQLite
The backend does not need direct USB access to the reader. A low-cost USB-C, USB-A, OTG, or Bluetooth HID RFID reader can type EPC codes into the browser, and the frontend forwards those codes to the API.
- Node.js 24 or newer
- npm
- Docker and Docker Compose, optional for containerized usage
This project currently uses Node's built-in SQLite API, so no native npm SQLite package or Visual Studio C++ build tools are required for local development.
npm installnpm run devDevelopment starts two services:
- API:
http://localhost:3000 - Frontend:
http://localhost:5173
The Vite frontend proxies /api requests to the Fastify backend.
npm run buildThe frontend is built into public/, and the TypeScript backend is built into dist/.
npm startThen open:
http://localhost:3000
docker compose up --buildThe app is exposed at:
http://localhost:3000
SQLite data is stored in the local data/ directory through the Docker volume mapping.
| Variable | Default | Purpose |
|---|---|---|
HOST |
0.0.0.0 |
Fastify bind host |
PORT |
3000 |
Fastify port |
DATABASE_URL |
data/inventory.sqlite |
SQLite database file |
NODE_ENV |
development |
Enables static frontend serving when set to production |
RFID_INPUT_MODE |
browser in Docker Compose |
Documents the intended reader mode |
APP_BASE_URL |
http://localhost:3000 in Docker Compose |
Public base URL hint |
Dashboard: review inventory activity, open sessions, and unknown tags.Inventory: start and stop container inventory sessions.Register Tag: scan an EPC and associate it with a new item.Items: create, edit, and archive inventory items.Sessions: reopen saved inventory sessions.Reader: test HID keyboard input, inspect raw input, and save station settings.Reports: review unknown tags and item last-seen data.
- Connect the RFID reader to the operator device.
- Open the app in a browser.
- Go to
Reader,Register Tag, orInventory. - Make sure the browser page is active.
- Scan a tag.
- The reader should type the EPC and usually submit it with Enter or Tab.
For Android devices, the reader must be supported as USB OTG, Bluetooth HID, or another keyboard-like input device.
GET /api/healthGET /api/itemsPOST /api/itemsGET /api/items/:idPUT /api/items/:idDELETE /api/items/:idGET /api/tagsGET /api/tags/:epcPOST /api/tags/registerPUT /api/tags/:epc/statusPOST /api/tags/mark-unknownPOST /api/rfid/browser-readPOST /api/rfid/batch-browser-readGET /api/inventory-sessionsPOST /api/inventory-sessionsGET /api/inventory-sessions/:sessionKeyPOST /api/inventory-sessions/:sessionKey/closeGET /api/stationsPOST /api/stationsGET /api/stations/:stationKeyPUT /api/stations/:stationKeyGET /api/reports/unknown-tagsGET /api/reports/items-last-seenGET /api/reports/session/:sessionKey/csvPOST /api/admin/backupPOST /api/admin/seed-demo
- Start the app.
- Click
Load Demo Data. - Open
Inventory. - Start a session.
- Use the demo scan buttons to simulate known and unknown RFID reads.
- Open
Reportsto review unknown tags and last-seen item data.
The demo EPC values are:
3034257BF7194E4000001A85
3034257BF7194E4000001A86
E2806894000040178F2A91B5
Click Create Backup in the sidebar or call:
curl -X POST http://localhost:3000/api/admin/backup \
-H "Content-Type: application/json" \
-d "{}"Backups are written under:
data/backups/
This project uses a custom source-available license. Free non-commercial use is allowed. Commercial use is reserved exclusively to the copyright holder. See LICENSE for the full terms.