Self-hosted dynamic QR codes with scan analytics. Pay once, own it forever. No subscription.
Print a QR code once — change where it points forever. QR Tracker generates dynamic QR codes that route through your own domain (/q/your-slug), so you can swap the destination any time without reprinting a single menu, poster, or business card. Every scan is tracked: totals, uniques, devices, countries, time-of-day.
It's the core of what QR Tiger charges $15+/month for — except it runs on your hardware, your QR codes never expire, and there is no "your plan lapsed, your codes are dead" hostage situation.
- Dynamic QR codes — the QR encodes
/q/:slugon your domain and 302-redirects to an editable destination. Reprint nothing, ever. - Scan analytics — total + unique scans, scans-over-time chart, device/OS/browser breakdown, country (via Cloudflare header), hour-of-day heatstrip, recent-scan log.
- 5 QR types — URL (dynamic + tracked), vCard (serves a
.vcfcontact download, also tracked), WiFi, plain text, email, phone. - Design studio — foreground/background colors, square / rounded / dots module styles, error-correction level, center logo upload, live preview.
- Print-ready export — PNG at 512 / 1024 / 2048 / 4096 px and true vector SVG.
- Batch generation — paste or drop a CSV (
name,destination) and get a zip of print-ready PNGs; every row becomes a tracked dynamic code. - Folders & tags — organize hundreds of codes per client, campaign, or location.
- 100% local & private — SQLite on disk, no telemetry, no external services.
npm i
npm run build # build the frontend once
npm start # → http://localhost:5308 (password: admin)Run it as a normal desktop app — no server admin needed:
npm run desktopThe Electron wrapper starts the same server on a free local port, stores data in your user profile, and opens a window already logged in. (First run downloads the Electron-ABI SQLite binding — one small file from better-sqlite3's official GitHub releases.)
Run it as a desktop app, or deploy to a $5 VPS when you need it public. Same code, both modes.
Note: dynamic QR codes encode the URL of the machine that generates them. For codes you'll print and distribute, deploy to a server with a domain and set
PUBLIC_URL— that's what ends up inside the QR.
cp .env.example .env # set ADMIN_PASSWORD and PUBLIC_URL
docker compose up -dPut it behind Cloudflare (free) and country analytics light up automatically via the CF-IPCountry header.
Want the packaged Windows installer with zero terminal time? Grab the one-time purchase:
→ Get QR Tracker on Whop — pay once, own it forever.
| QR Tracker | QR Tiger Pro | |
|---|---|---|
| Price | $24 once | $15/month, forever |
| Dynamic (editable) QR codes | ✅ Unlimited | Capped by plan |
| Codes keep working if you stop paying | ✅ Always — you host them | ❌ Codes die with your plan |
| Scan analytics | ✅ Included | ✅ Included |
| Custom colors, dot styles, logo | ✅ Included | ✅ Included |
| Batch CSV generation | ✅ Included | Higher tiers |
| Your scan data stays private | ✅ Your SQLite file | ❌ Their cloud |
| API / redirect domain | ✅ Yours | Theirs (qrco.de) |
| 12-month cost | $24 | $180+ |
- Server: Node 20+, Express, better-sqlite3 (WAL),
qrcodefor matrix generation, custom SVG renderer for styled modules,sharpfor rasterization + logo compositing,ua-parser-js,archiver - Frontend: React 19 + Vite, Tailwind CSS 4, Framer Motion, Lucide icons
- Desktop: thin Electron wrapper around the same Express server (electron-builder NSIS config included)
- Tests:
npm testruns an end-to-end smoke test that actually decodes generated PNGs with jsQR, hits the redirect, and asserts scan rows land
npm test exercises the real server: creates a dynamic code → decodes the rendered PNG with jsQR and asserts it encodes the /q/ URL → scans it twice with different user agents → asserts the 302, 2 scan rows, and analytics → edits the destination and proves the same QR follows → renders rounded/dots styles with a center logo and asserts they still decode → vCard returns a .vcf → batch CSV returns a zip.
MIT © 2026 Ben (bensblueprints)