react-qr-code vs react-qr-reader vs react-qr-scanner
Implementing QR Code Generation and Scanning in React Applications
react-qr-codereact-qr-readerreact-qr-scanner

Implementing QR Code Generation and Scanning in React Applications

react-qr-code, react-qr-reader, and react-qr-scanner address two distinct sides of the QR code workflow: generation and scanning. react-qr-code is a dedicated library for rendering QR codes as SVG or Canvas elements directly within React components, making it ideal for displaying dynamic data like tickets or Wi-Fi credentials. In contrast, react-qr-reader and react-qr-scanner focus on capturing and decoding QR codes from camera feeds or image files. While react-qr-reader was an early standard for this functionality, it is now deprecated and unmaintained. react-qr-scanner serves as its modern, actively maintained successor, offering improved browser compatibility, better handling of media streams, and continued support for contemporary React versions.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
react-qr-code089319.9 kB83 months agoMIT
react-qr-reader01,1514.38 MB149-MIT
react-qr-scanner0-2.1 MB--ISC

QR Code Generation vs. Scanning: Choosing the Right React Tools

When building applications that interact with QR codes, developers usually face one of two distinct challenges: generating a code for users to scan, or scanning a code presented by the user. The ecosystem offers three notable packages to handle these tasks, but they serve very different purposes and carry different levels of risk. Let's break down how react-qr-code, react-qr-reader, and react-qr-scanner work under the hood and when to use them.

🎨 Generating Codes: The Role of react-qr-code

react-qr-code is purely a rendering engine. It takes a string value and converts it into a visual QR code using SVG or Canvas. It does not access your camera, nor does it decode images. Its main strength lies in its simplicity and scalability β€” since it often defaults to SVG, the output looks crisp on any device, from mobile phones to large displays.

This package is ideal for generating dynamic content, such as one-time login tokens, Wi-Fi connection strings, or payment links. You simply pass the data as a prop, and the component handles the complex math of encoding that data into the black-and-white pattern.

// react-qr-code: Generating a Wi-Fi login QR
import QRCode from 'react-qr-code';

function WifiTicket() {
  const wifiString = 'WIFI:S:MyNetwork;T:WPA;P:secret123;;';

  return (
    <div style={{ height: 'auto', margin: '0 auto', maxWidth: 256, width: '100%' }}>
      <QRCode
        size={256}
        style={{ height: 'auto', maxWidth: '100%', width: '100%' }}
        value={wifiString}
        viewBox={`0 0 256 256`}
      />
    </div>
  );
}

πŸ“· Scanning Codes: The Legacy vs. The Modern Standard

For scanning, the landscape has shifted. Historically, react-qr-reader was the go-to solution. It wrapped browser media APIs to access the webcam and used a JavaScript decoding library to interpret the video stream. However, the maintenance of this package has stopped. It is now marked as deprecated, meaning it will not receive updates for security vulnerabilities or compatibility with new browser standards.

react-qr-scanner emerged as the community-driven successor to fix these issues. It retains a similar API surface to make migration easier but updates the underlying dependencies to handle modern browser permissions, better error handling for camera access, and improved performance on mobile devices. If you are starting a new project today, react-qr-scanner is the only safe choice for scanning functionality.

// react-qr-scanner: Modern scanning implementation
import { Scanner } from '@yudiel/react-qr-scanner';

function ModernScanner({ onResult }) {
  return (
    <Scanner
      onScan={(result) => onResult(result?.[0]?.text)}
      onError={(error) => console.log(error?.message)}
      scanDelay={500}
    />
  );
}
// react-qr-reader: Deprecated legacy implementation (DO NOT USE)
import QrReader from 'react-qr-reader';

function LegacyScanner({ onResult }) {
  return (
    <QrReader
      delay={300}
      onError={(error) => console.log(error)}
      onResult={(result) => {
        if (result) {
          onResult(result.getText());
        }
      }}
      style={{ width: '100%' }}
    />
  );
}

βš™οΈ Handling Camera Permissions and Errors

Accessing the camera is a sensitive operation that requires explicit user permission. Both scanning libraries handle this, but their approaches to error reporting differ due to their age.

react-qr-scanner provides a dedicated onError prop that captures modern DOMExceptions, such as when a user denies permission or when no camera device is found. It allows you to gracefully degrade the UI, perhaps showing a manual text input field instead of crashing the app.

react-qr-reader also had an onError handler, but because it is no longer updated, it may not correctly interpret newer browser error codes or handle edge cases on iOS Safari, which has strict autoplay and camera policies. Relying on it can lead to silent failures where the camera simply never starts.

// react-qr-scanner: Robust error handling
<Scanner
  onScan={(result) => console.log(result)}
  onError={(error) => {
    if (error?.message?.includes('permission')) {
      alert('Please allow camera access to scan codes.');
    }
  }}
/>
// react-qr-reader: Legacy error handling (Unreliable on new browsers)
<QrReader
  onResult={(result) => console.log(result)}
  onError={(error) => {
    // May not catch specific modern permission errors reliably
    console.error('Camera error:', error);
  }}
/>

πŸ–ΌοΈ Scanning from Uploaded Images

Sometimes users cannot point their camera at a code β€” maybe they have a screenshot saved on their device. Both libraries historically supported scanning from file inputs, but the implementation in the maintained library is more robust.

react-qr-scanner supports scanning from image files directly through its configuration or by passing a file reference, ensuring the decoding logic works with modern image blob formats. This is crucial for web apps where users might upload a ticket screenshot.

react-qr-reader required specific props to handle image files, and its underlying decoding engine is outdated. It may struggle with newer image compression formats or high-resolution screenshots that modern phones produce.

// react-qr-scanner: Scanning from an image file
// Note: Implementation often involves passing the file to the scanner component
// or using a dedicated image scanning mode if supported by the version.
<Scanner
  onScan={(result) => console.log('Scanned from image:', result)}
  // Specific props for image scanning may vary by version, 
  // but the library actively maintains these features.
/>
// react-qr-reader: Legacy image scanning (Fragile)
<QrReader
  // Legacy approach often required separate logic or specific constraints
  // to handle file inputs reliably.
  constraints={{ video: false }} // Hypothetical legacy constraint
/>

πŸ”„ Migration Path for Existing Projects

If your codebase currently uses react-qr-reader, you should treat it as technical debt. The migration to react-qr-scanner is generally straightforward because the core concept remains the same: a component that renders a video element and calls a callback with the decoded text.

The main changes involve updating the import paths, adjusting the callback signatures (as react-qr-scanner often returns an array of results or a specific result object rather than a raw string directly in some versions), and ensuring your build pipeline supports the newer dependencies. Making this switch ensures your application remains secure and functional as browsers evolve.

// Migration Example: Switching imports and result handling

// OLD (react-qr-reader)
// import QrReader from 'react-qr-reader';
// onResult={(result) => result && setData(result.getText())}

// NEW (react-qr-scanner)
import { Scanner } from '@yudiel/react-qr-scanner';
// onScan={(result) => result && setData(result[0]?.text)}

πŸ“Š Summary: Capabilities and Status

Featurereact-qr-codereact-qr-readerreact-qr-scanner
Primary FunctionGenerate / Display QR CodesScan / Decode QR CodesScan / Decode QR Codes
Maintenance Statusβœ… Active❌ Deprecatedβœ… Active
Input SourceText StringCamera / Image FileCamera / Image File
Output FormatSVG / CanvasDecoded Text StringDecoded Text / Object
Browser SupportHigh (SVG based)Low (Legacy APIs)High (Modern APIs)
Recommended ForAll new generation tasksNone (Legacy only)All new scanning tasks

πŸ’‘ Final Recommendation

Your choice depends entirely on whether you are creating a code or reading one.

If you need to display a QR code, react-qr-code is the industry standard. It is lightweight, dependency-free (regarding camera APIs), and produces scalable vector graphics that look professional on any device.

If you need to scan a QR code, you must use react-qr-scanner. It provides the same functionality as the old react-qr-reader but with the critical benefit of active maintenance. Using the deprecated react-qr-reader in a new project is a significant risk, as it may break with future browser updates or React versions. Stick to the maintained tools to ensure your application remains robust and secure.

How to Choose: react-qr-code vs react-qr-reader vs react-qr-scanner

  • react-qr-code:

    Choose react-qr-code when your primary requirement is to generate and display QR codes within your application interface. It is the standard choice for rendering static or dynamic data (like URLs or payment info) as high-quality SVGs that scale perfectly on any screen resolution. Use this if you do not need camera access or decoding capabilities, as it focuses solely on the visual representation of the code.

  • react-qr-reader:

    Do NOT choose react-qr-reader for any new projects. This package is officially deprecated and no longer receives security updates or bug fixes. It relies on older browser APIs that may break in modern environments and lacks support for recent React versions. Existing projects using this library should plan an immediate migration to react-qr-scanner to ensure stability and security.

  • react-qr-scanner:

    Choose react-qr-scanner when you need to implement QR code decoding from a live camera feed or uploaded images in a modern React application. It is the direct, maintained replacement for react-qr-reader, offering better performance, active community support, and compatibility with current browser media stream standards. Select this package if you require a reliable, drop-in solution for scanning functionality without the technical debt of deprecated dependencies.

README for react-qr-code

react-qr-code

npm package

A component for React. This library works with React and React Native (using React Native SVG).

Screenshots

Web

Android & iOS

Installation

npm i react-qr-code

When using this library with React Native, you will also need to have react-native-svg installed.

npm i react-native-svg
cd ios && pod install

The Gist

import React from "react";
import ReactDOM from "react-dom";
import QRCode from "react-qr-code";

ReactDOM.render(<QRCode value="hey" />, document.getElementById("Container"));

Note: If the QR code is likely to appear next to dark objects, you will need to wrap it in a light-colored container to preserve the 'quiet zone', e.g.

<div style={{ background: 'white', padding: '16px' }}>
  <QRCode ... />
</div>

Responsive QR code example:

// Can be anything instead of `maxWidth` that limits the width.
<div style={{ height: "auto", margin: "0 auto", maxWidth: 64, width: "100%" }}>
  <QRCode
    size={256}
    style={{ height: "auto", maxWidth: "100%", width: "100%" }}
    value={value}
    viewBox={`0 0 256 256`}
  />
</div>

API

proptypedefault valueplatform
bgColorstring'#FFFFFF'web, ios, android
fgColorstring'#000000'web, ios, android
levelstring ('L' 'M' 'Q' 'H')'L'web, ios, android
sizenumber256web, ios, android
titlestringweb
valuestringweb, ios, android

Adheres to the official QR spec and can store up to 2953 characters in value.

Non-ASCII / UTF-8 text

react-qr-code encodes data in UTF-8 byte mode to ensure non-ASCII text (e.g., Korean, Japanese, emoji) renders and scans correctly. Just pass a normal JavaScript string:

<QRCode value="ν•œκΈ€ ν…ŒμŠ€νŠΈ 😊" />

No additional encoding is required on your side.

Testing UTF-8 locally

  1. Build the demo library bundle in watch mode:
    • In one terminal: npm run demo-web-watch
  2. Run the demo app:
    • In another terminal: npm run demo
  3. Open the demo in your browser (Expo starts it automatically) and type a non-ASCII value (e.g., μ•ˆλ…•ν•˜μ„Έμš”, こんにけは, or an emoji) into the input.
  4. Scan the QR code with a phone camera app. The decoded text should match exactly.

License

MIT