Lightweight QR Code Scanner
qr-scanner is a JavaScript library designed for efficient QR code scanning from both continuous video streams (webcams) and static images. Currently at version 1.4.2, it appears to be actively maintained, supported by Nimiq, and offers significant performance and accuracy advantages over older libraries like LazarSoft/jsqrcode, boasting a 2-8x higher detection rate and fewer misreads according to benchmarks. Key differentiators include its lightweight footprint (as low as 5.6 kB gzipped when `BarcodeDetector` is available), automatic utilization of the browser's native `BarcodeDetector` API for optimal performance, and its design to run in a WebWorker to keep the main UI thread responsive. The library is built upon Cosmo Wolfe's JavaScript port of Google's ZXing library, with several improvements geared towards modern web environments and optimized for colored QR codes.
Common errors
-
Uncaught SyntaxError: Cannot use import statement outside a module
cause Attempting to use `import` syntax in a JavaScript file that is not treated as an ES module (e.g., a standard `<script>` tag without `type="module"`).fixChange your `<script>` tag to `<script type="module">` or load the UMD build (`qr-scanner.umd.min.js`) directly via a standard `<script>` tag, which exposes `QrScanner` globally. -
Failed to load module script: The server responded with a non-JavaScript MIME type of "" (or 404 Not Found) for "[path]/qr-scanner-worker.min.js".
cause The browser could not find or load the web worker script (`qr-scanner-worker.min.js`) at the specified path, often due to incorrect file placement, an incorrect `QrScanner.workerScript` path, or a server configuration issue.fixVerify that `qr-scanner-worker.min.js` is physically located in your public assets directory, that `QrScanner.workerScript` is set to the correct URL relative to your HTML page or domain root, and that your web server serves `.js` files with the `application/javascript` MIME type. -
TypeError: QrScanner is not a constructor
cause This usually occurs when `QrScanner` is not correctly imported or exposed in the current scope. Common causes include using `require()` on an ES module, or importing a UMD build that expects global access.fixEnsure you are using the correct import strategy for your environment: `import QrScanner from 'qr-scanner';` for ES Modules (with bundler), `import QrScanner from './path/to/qr-scanner.min.js';` for plain browser ES Modules, or `const QrScanner = require('qr-scanner/qr-scanner.umd.min.js');` for CommonJS.
Warnings
- gotcha The `qr-scanner-worker.min.js` file is loaded dynamically and *must* be accessible at the path specified by `QrScanner.workerScript`. If you're not using a bundler that handles web workers (like some versions of Webpack with appropriate loaders), or if your bundler doesn't copy the file to the correct output directory, you will need to manually copy `qr-scanner-worker.min.js` to a public path where your main script can find it.
- gotcha The primary `qr-scanner` package is distributed as an ES Module. Attempting to `require('qr-scanner')` directly in a CommonJS context without a bundler that transpiles ESM to CJS, or without explicitly importing the UMD build (`qr-scanner.umd.min.js`), will lead to module loading errors.
- gotcha The library utilizes ECMAScript 2017 features, including `async` functions. If targeting older browsers that do not natively support these features, you may need to include appropriate polyfills (e.g., via Babel) in your project to ensure compatibility.
- gotcha The performance and capabilities of `qr-scanner` can vary significantly based on browser support for the native `BarcodeDetector` API. While the library falls back to its internal engine, optimal performance (including smaller bundle size) is achieved when `BarcodeDetector` is available.
Install
-
npm install qr-scanner -
yarn add qr-scanner -
pnpm add qr-scanner
Imports
- QrScanner
const QrScanner = require('qr-scanner');import QrScanner from 'qr-scanner';
- QrScanner
import { QrScanner } from 'qr-scanner';import QrScanner from './path/to/qr-scanner.min.js';
- QrScanner
import QrScanner from 'qr-scanner/qr-scanner.umd.min.js';
const QrScanner = require('qr-scanner/qr-scanner.umd.min.js');
Quickstart
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>QR Scanner Demo</title>
</head>
<body>
<h1>Scan QR Code</h1>
<video id="qr-video" style="width: 100%; max-width: 400px;"></video>
<div id="qr-result"></div>
<script type="module">
import QrScanner from 'qr-scanner'; // Adjust path if not using a bundler
// You need to copy qr-scanner-worker.min.js to a public path or configure your bundler
// If qr-scanner-worker.min.js is in the same directory as this script:
QrScanner.workerScript = './qr-scanner-worker.min.js';
// If using npm and a bundler, it might be resolved automatically or you might need to copy it.
// If deployed to a 'dist' folder, and worker is in 'dist/':
// QrScanner.workerScript = '/dist/qr-scanner-worker.min.js';
const videoElement = document.getElementById('qr-video');
const resultElement = document.getElementById('qr-result');
const qrScanner = new QrScanner(
videoElement,
result => {
resultElement.textContent = `QR Code detected: ${result.data}`;
console.log('QR Code detected:', result.data);
// To stop scanning after first detection:
// qrScanner.stop();
},
{
/* your options or pass nothing */
highlightScanRegion: true,
highlightCodeOutline: true,
returnDetailedScanResult: true
}
);
// Start scanning immediately when the page loads
qrScanner.start().then(() => {
console.log('QR Scanner started');
}).catch(err => {
console.error('Failed to start QR Scanner:', err);
resultElement.textContent = `Error starting scanner: ${err.message || err}`;
});
// Optional: Stop scanner when component unmounts or page navigates
// window.addEventListener('beforeunload', () => {
// qrScanner.stop();
// });
</script>
</body>
</html>