react-qr-reader

A lightweight React component and hook for scanning QR codes directly from a device's webcam.

Library
npm
v3.0.0-beta-1
1,151stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
45/100Fair
Development Activity0
Maintenance20
Community72
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
48/100Fair
Architecture72
Code Quality35
Innovation30
Learning Curve55

react-qr-reader is a small React component library that turns a device camera into a QR code scanner using the browser’s MediaDevices API and ZXing’s decoding engine. It renders a QrReader component that requests camera access, streams video into a hidden <video> element, and continuously decodes QR codes from the feed, invoking a callback with each result or error.

Built as a thin, hooks-based wrapper (useQrReader) around @zxing/browser’s BrowserQRCodeReader, the library favors a single focused job over a broad feature set: no bundled state management, no UI chrome beyond the video element, and full control over styling and the scan overlay left to the consumer via a ViewFinder render prop.

What You Get

  • A ready-to-use <QrReader> React component that requests camera access and renders the live video feed
  • A useQrReader hook exposing the same scanning logic for custom UI compositions
  • A configurable constraints prop for selecting the front/rear camera or other MediaTrackConstraints
  • An optional ViewFinder render-prop slot for overlaying a custom scan-target graphic
  • TypeScript type definitions shipped with the package

Common Use Cases

  • Scanning QR codes for ticket or badge check-in at events
  • Reading QR codes to prefill URLs or form data in web apps
  • Building browser-based inventory or asset-tagging tools
  • Adding camera-based two-factor/auth-key onboarding flows to a web app

Under The Hood

Architecture The project is a small, flat library: src/index.ts re-exports the public API, QrReader/index.tsx is a purely presentational component, QrReader/hooks.ts holds the useQrReader hook that owns all camera/decode logic, QrReader/utils.ts holds small runtime guards, and types/index.ts centralizes prop and callback typings. This is a clean separation between rendering and behavior — the component itself has no knowledge of @zxing/browser, it simply calls the hook and renders a <video> plus an optional ViewFinder — but the surface is small enough that there is no abstraction layer between the hook and its one decoding dependency, so a change to @zxing/browser’s decodeFromConstraints API would ripple directly into hooks.ts.

Tech Stack Written in TypeScript and compiled with Rollup into separate CJS and ESM bundles (@rollup/plugin-typescript, @rollup/plugin-commonjs, @rollup/plugin-node-resolve, rollup-plugin-terser, rollup-plugin-dts for type-only output), with React (>=16.8, hooks-based) as a peer dependency and @zxing/browser/@zxing/library as the sole runtime dependencies for QR decoding. Storybook 6 is used for local component development and demos, deployed to GitHub Pages via storybook-to-ghpages. ESLint (eslint-config-react-app plus the hooks plugin) and Prettier enforce style, and Husky/lint-staged plus commitlint gate commits with conventional-commit formatting.

Code Quality No automated test files exist anywhere in the repository — verification is limited to manual use of the Storybook stories, and there is no CI workflow (only a Dependabot config) to run lint or build checks on push. Errors are surfaced through the onResult callback’s error argument rather than thrown, and a shared isValidType() guard logs a console warning when a prop has the wrong type rather than failing loudly. TypeScript is used throughout, but tsconfig.json disables strictNullChecks and noImplicitAny, so several prop types (containerStyle, videoStyle) fall back to any.

What Makes It Unique The library doesn’t implement QR decoding itself — it wraps @zxing/browser’s existing decoder in a small, hooks-based React component, contributing camera-permission handling, a managed decode loop, and a ViewFinder render-prop slot on top. This is a common pattern among comparable webcam-QR React wrappers, so the value here is ergonomic convenience rather than a novel scanning technique.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search