### Install @zxing/browser and @zxing/library
Source: https://context7.com/zxing-js/browser/llms.txt
Install the necessary packages for barcode scanning in the browser. Use npm or yarn.
```bash
npm install @zxing/browser @zxing/library
# or
yarn add @zxing/browser @zxing/library
```
--------------------------------
### Install ZXing Browser via NPM
Source: https://github.com/zxing-js/browser/blob/master/README.md
Use this command to add the ZXing browser library to your project using NPM.
```bash
npm i @zxing/browser
```
--------------------------------
### Install ZXing Browser via Yarn
Source: https://github.com/zxing-js/browser/blob/master/README.md
Use this command to add the ZXing browser library to your project using Yarn.
```bash
yarn add @zxing/browser
```
--------------------------------
### Scan from Webcam Continuously
Source: https://github.com/zxing-js/browser/blob/master/README.md
Continuously scan barcodes from a selected webcam device. This example lists available devices, selects the first one, and starts decoding into a video element. It includes logic to stop scanning after a set duration.
```typescript
const codeReader = new BrowserQRCodeReader();
const videoInputDevices = await ZXingBrowser.BrowserCodeReader.listVideoInputDevices();
// choose your media device (webcam, frontal camera, back camera, etc.)
const selectedDeviceId = videoInputDevices[0].deviceId;
console.log(`Started decode from camera with id ${selectedDeviceId}`);
const previewElem = document.querySelector('#test-area-qr-code-webcam > video');
// you can use the controls to stop() the scan or switchTorch() if available
const controls = await codeReader.decodeFromVideoDevice(selectedDeviceId, previewElem, (result, error, controls) => {
// use the result and error values to choose your actions
// you can also use controls API in this scope like the controls
// returned from the method.
});
// stops scanning after 20 seconds
setTimeout(() => controls.stop(), 20000);
```
--------------------------------
### Import ZXingBrowser as ES6 Module
Source: https://github.com/zxing-js/browser/blob/master/README.md
Import the BrowserQRCodeReader class from the ZXing browser library using ES6 module syntax.
```html
```
--------------------------------
### BrowserCodeReader.listVideoInputDevices()
Source: https://context7.com/zxing-js/browser/llms.txt
Lists all available video input devices on the system. This static method uses `navigator.mediaDevices.enumerateDevices()` and returns a Promise resolving to an array of `MediaDeviceInfo` objects. It's useful for creating user interfaces that allow selection of different cameras.
```APIDOC
## BrowserCodeReader.listVideoInputDevices()
### Description
Static method that enumerates all `videoinput` devices available in the browser via `navigator.mediaDevices.enumerateDevices()`. Returns a `Promise`. Useful for building device-picker UIs.
### Method
`static async listVideoInputDevices(): Promise`
### Example
```typescript
import { BrowserCodeReader } from '@zxing/browser';
async function buildDevicePicker() {
const devices = await BrowserCodeReader.listVideoInputDevices();
if (devices.length === 0) {
console.warn('No video input devices found.');
return;
}
const select = document.getElementById('camera-select') as HTMLSelectElement;
devices.forEach((device) => {
const option = document.createElement('option');
option.value = device.deviceId;
option.text = device.label || `Camera ${device.deviceId.slice(0, 8)}`;
select.appendChild(option);
});
}
```
```
--------------------------------
### Import ZXingBrowser with AMD
Source: https://github.com/zxing-js/browser/blob/master/README.md
Import the ZXingBrowser module using RequireJS for AMD environments. The library is exposed as ZXingBrowser.
```html
```
--------------------------------
### IBrowserCodeReaderOptions
Source: https://context7.com/zxing-js/browser/llms.txt
Configuration interface for reader constructors to control scanning timing and video playback. Options include delayBetweenScanSuccess, delayBetweenScanAttempts, and tryPlayVideoTimeout.
```APIDOC
## IBrowserCodeReaderOptions
### Description
Configuration interface passed to any reader constructor to control scanning timing and video playback behavior.
### Properties
- **delayBetweenScanSuccess** (number) - Optional - Milliseconds to wait between successive successful decode results (default: 500).
- **delayBetweenScanAttempts** (number) - Optional - Milliseconds to wait between decode attempts when nothing is found (default: 500).
- **tryPlayVideoTimeout** (number) - Optional - Milliseconds to wait for the video 'canplay' event before timing out (default: 5000).
### Example
```typescript
import { BrowserQRCodeReader, IBrowserCodeReaderOptions } from '@zxing/browser';
const options: IBrowserCodeReaderOptions = {
delayBetweenScanSuccess: 300,
delayBetweenScanAttempts: 200,
tryPlayVideoTimeout: 10000,
};
const reader = new BrowserQRCodeReader(undefined, options);
```
```
--------------------------------
### BrowserCodeReader - Static Utility Methods
Source: https://context7.com/zxing-js/browser/llms.txt
A collection of static helper methods for device management, element creation, stream handling, and bitmap preparation.
```APIDOC
## BrowserCodeReader - Static Utility Methods
### Description
A collection of static helpers for device management, element creation, stream handling, and bitmap preparation.
### Methods
#### `mediaStreamIsTorchCompatible(stream: MediaStream): boolean`
Checks if the media stream supports torch functionality.
#### `mediaStreamSetTorch(track: MediaStreamTrack, enable: boolean): Promise`
Controls the torch (flash) on a media stream track. This is an experimental feature.
#### `releaseAllStreams(): void`
Releases all tracked media streams.
#### `createCanvasFromMediaElement(videoElement: HTMLVideoElement): HTMLCanvasElement`
Creates a canvas snapshot from the current frame of a video element.
#### `createBinaryBitmapFromCanvas(canvas: HTMLCanvasElement): BinaryBitmap`
Creates a `BinaryBitmap` from a canvas element, useful for custom decoding pipelines.
#### `isVideoPlaying(videoElement: HTMLVideoElement): boolean`
Checks if a video element is currently playing.
#### `prepareVideoElement(videoId?: string): HTMLVideoElement`
Prepares a video element for use, ensuring autoplay, muted, and playsinline properties are set. Can create a new element or prepare an existing one by ID.
#### `cleanVideoSource(videoElement: HTMLVideoElement): void`
Cleans up the source of a video element.
### Request Example
```typescript
import { BrowserCodeReader } from '@zxing/browser';
// --- Media stream torch control (experimental) ---
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const track = stream.getVideoTracks()[0];
if (BrowserCodeReader.mediaStreamIsTorchCompatible(stream)) {
await BrowserCodeReader.mediaStreamSetTorch(track, true); // torch on
await BrowserCodeReader.mediaStreamSetTorch(track, false); // torch off
}
// --- Release all tracked streams ---
BrowserCodeReader.releaseAllStreams();
// --- Create a canvas snapshot from a video element ---
const videoEl = document.getElementById('cam') as HTMLVideoElement;
const canvas = BrowserCodeReader.createCanvasFromMediaElement(videoEl);
// canvas now holds the current video frame, ready for decoding
// --- Create a BinaryBitmap from a canvas (for custom decode pipelines) ---
const bitmap = BrowserCodeReader.createBinaryBitmapFromCanvas(canvas);
// --- Check if a video is currently playing ---
const isPlaying = BrowserCodeReader.isVideoPlaying(videoEl);
console.log('Playing:', isPlaying);
// --- Prepare a video element (autoplay, muted, playsinline for iOS) ---
const preparedVideo = BrowserCodeReader.prepareVideoElement();
// or from existing element:
const preparedFromId = BrowserCodeReader.prepareVideoElement('my-video-id');
// --- Clean up a video element's source ---
BrowserCodeReader.cleanVideoSource(videoEl);
```
```
--------------------------------
### Import ZXingBrowser with UMD
Source: https://github.com/zxing-js/browser/blob/master/README.md
Load the ZXing browser library using a UMD-compatible script tag and access it via the ZXingBrowser global variable after the DOM is loaded.
```html
```
--------------------------------
### BrowserCodeReader Static Utility Methods
Source: https://context7.com/zxing-js/browser/llms.txt
Provides static helpers for media stream torch control, releasing streams, creating canvas snapshots, generating BinaryBitmaps, checking video playback, preparing video elements, and cleaning video sources.
```typescript
import { BrowserCodeReader } from '@zxing/browser';
// --- Media stream torch control (experimental) ---
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
const track = stream.getVideoTracks()[0];
if (BrowserCodeReader.mediaStreamIsTorchCompatible(stream)) {
await BrowserCodeReader.mediaStreamSetTorch(track, true); // torch on
await BrowserCodeReader.mediaStreamSetTorch(track, false); // torch off
}
// --- Release all tracked streams ---
BrowserCodeReader.releaseAllStreams();
// --- Create a canvas snapshot from a video element ---
const videoEl = document.getElementById('cam') as HTMLVideoElement;
const canvas = BrowserCodeReader.createCanvasFromMediaElement(videoEl);
// canvas now holds the current video frame, ready for decoding
// --- Create a BinaryBitmap from a canvas (for custom decode pipelines) ---
const bitmap = BrowserCodeReader.createBinaryBitmapFromCanvas(canvas);
// --- Check if a video is currently playing ---
const isPlaying = BrowserCodeReader.isVideoPlaying(videoEl);
console.log('Playing:', isPlaying);
// --- Prepare a video element (autoplay, muted, playsinline for iOS) ---
const preparedVideo = BrowserCodeReader.prepareVideoElement();
// or from existing element:
const preparedFromId = BrowserCodeReader.prepareVideoElement('my-video-id');
// --- Clean up a video element's source ---
BrowserCodeReader.cleanVideoSource(videoEl);
```
--------------------------------
### Asynchronous ES6 Module Import
Source: https://github.com/zxing-js/browser/blob/master/README.md
Import the BrowserQRCodeReader class asynchronously using dynamic import syntax for ES6 modules.
```html
```
--------------------------------
### List Video Input Devices with BrowserCodeReader
Source: https://context7.com/zxing-js/browser/llms.txt
Enumerates all video input devices available in the browser. Useful for building device-picker UIs.
```typescript
import { BrowserCodeReader } from '@zxing/browser';
async function buildDevicePicker() {
const devices = await BrowserCodeReader.listVideoInputDevices();
if (devices.length === 0) {
console.warn('No video input devices found.');
return;
}
const select = document.getElementById('camera-select') as HTMLSelectElement;
devices.forEach((device) => {
const option = document.createElement('option');
option.value = device.deviceId;
option.text = device.label || `Camera ${device.deviceId.slice(0, 8)}`;
select.appendChild(option);
});
// Expected output in select:
// "Back Camera (HD)" | deviceId: "abc123..."
// "Front Camera" | deviceId: "def456..."
}
```
--------------------------------
### Configure BrowserCodeReader Options
Source: https://context7.com/zxing-js/browser/llms.txt
Customize scanning behavior by providing an options object to the reader constructor. Adjust delays between scans and video playback timeouts.
```typescript
import { BrowserQRCodeReader, IBrowserCodeReaderOptions } from '@zxing/browser';
const options: IBrowserCodeReaderOptions = {
// Milliseconds to wait between successive successful decode results (default: 500)
delayBetweenScanSuccess: 300,
// Milliseconds to wait between decode attempts when nothing is found (default: 500)
delayBetweenScanAttempts: 200,
// Milliseconds to wait for the video 'canplay' event before timing out (default: 5000)
tryPlayVideoTimeout: 10000,
};
const reader = new BrowserQRCodeReader(undefined, options);
```
--------------------------------
### Include @zxing/browser via CDN
Source: https://context7.com/zxing-js/browser/llms.txt
Include the UMD bundle of the @zxing/browser library directly in your HTML using a CDN link.
```html
```
--------------------------------
### Decode Once from Video Device with BrowserQRCodeReader
Source: https://context7.com/zxing-js/browser/llms.txt
Single-shot version of decodeFromVideoDevice. Resolves with the first successfully decoded Result and automatically stops the scanner. Rejects on unrecoverable errors.
```typescript
import { BrowserQRCodeReader } from '@zxing/browser';
const reader = new BrowserQRCodeReader();
try {
const result = await reader.decodeOnceFromVideoDevice(
undefined, // rear/environment camera
document.getElementById('preview') as HTMLVideoElement,
);
console.log('QR code content:', result.getText());
// e.g. "https://example.com"
} catch (err) {
console.error('Failed to decode:', err);
}
```
--------------------------------
### Decode from Video Device with BrowserQRCodeReader
Source: https://context7.com/zxing-js/browser/llms.txt
Continuously scans from a specific camera device, rendering the live feed into an optional video preview element. Stops scanning after the first successful decode when ctrl.stop() is called within the callback.
```typescript
import { BrowserQRCodeReader } from '@zxing/browser';
const reader = new BrowserQRCodeReader(undefined, { delayBetweenScanAttempts: 100 });
const videoEl = document.getElementById('webcam-preview') as HTMLVideoElement;
// Pass undefined as deviceId to auto-select the rear camera
const controls = await reader.decodeFromVideoDevice(undefined, videoEl, (result, err, ctrl) => {
if (result) {
document.getElementById('output')!.textContent = result.getText();
ctrl.stop(); // stop after first decode
}
});
// Stop from outside the callback
document.getElementById('stop-btn')!.addEventListener('click', () => controls.stop());
```
--------------------------------
### Find Video Device by ID with BrowserCodeReader
Source: https://context7.com/zxing-js/browser/llms.txt
Lists all video input devices and returns the MediaDeviceInfo entry matching the supplied deviceId, or undefined if not found. Use this to select a specific camera.
```typescript
import { BrowserCodeReader } from '@zxing/browser';
const targetId = 'abc123...'; // previously stored device ID
const device = await BrowserCodeReader.findDeviceById(targetId);
if (device) {
console.log(`Found device: ${device.label}`);
} else {
console.warn('Device not found — it may have been disconnected.');
}
```
--------------------------------
### Decode from MediaStream with BrowserQRCodeReader
Source: https://context7.com/zxing-js/browser/llms.txt
Attaches an already-obtained MediaStream to the scanner for decoding. Useful when you acquire the stream yourself for other purposes, like recording.
```typescript
import { BrowserQRCodeReader } from '@zxing/browser';
const stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'environment' } });
const reader = new BrowserQRCodeReader();
const controls = await reader.decodeFromStream(
stream,
document.getElementById('preview') as HTMLVideoElement,
(result, error, ctrl) => {
if (result) {
console.log('Scanned:', result.getText());
ctrl.stop();
}
},
);
```
--------------------------------
### Decode from MediaStreamConstraints with BrowserMultiFormatReader
Source: https://context7.com/zxing-js/browser/llms.txt
Continuous scan using raw MediaStreamConstraints for fine-grained control over camera resolution, frame rate, or facing mode. Requires a video element to display the feed.
```typescript
import { BrowserMultiFormatReader } from '@zxing/browser';
const reader = new BrowserMultiFormatReader();
const constraints: MediaStreamConstraints = {
video: {
facingMode: { ideal: 'environment' },
width: { ideal: 1280 },
height: { ideal: 720 },
frameRate: { ideal: 30 },
},
};
const controls = await reader.decodeFromConstraints(
constraints,
document.getElementById('preview') as HTMLVideoElement,
(result, error) => {
if (result) console.log('Barcode:', result.getText(), '| Format:', result.getBarcodeFormat());
},
);
```
--------------------------------
### Include ZXing Browser via Script Tag
Source: https://github.com/zxing-js/browser/blob/master/README.md
Include the ZXing browser library directly in your HTML using a script tag from a CDN like UNPKG.
```html
```
--------------------------------
### Low-Level Continuous Scan Loop - TypeScript
Source: https://context7.com/zxing-js/browser/llms.txt
Provides a low-level, continuous scanning loop that operates directly on an HTMLVideoElement or HTMLImageElement. It drives the internal decode-on-interval mechanism used by higher-level methods and returns IScannerControls synchronously. Configuration options for scan attempt and success delays are available.
```typescript
import { BrowserQRCodeReader } from '@zxing/browser';
const reader = new BrowserQRCodeReader(undefined, {
delayBetweenScanAttempts: 150,
delayBetweenScanSuccess: 1000,
});
const videoEl = document.getElementById('preview') as HTMLVideoElement;
const controls = reader.scan(
videoEl,
(result, error, ctrl) => {
if (result) {
console.log('scan() result:', result.getText());
}
},
() => {
// finalizeCallback: called when scan loop ends (via stop() or fatal error)
console.log('Scan loop finalized.');
},
);
// Stop from a button
document.getElementById('stop')!.onclick = () => controls.stop();
```
--------------------------------
### BrowserCodeReader.decodeOnceFromVideoDevice()
Source: https://context7.com/zxing-js/browser/llms.txt
Performs a single scan from a video device. This method is a convenience wrapper around `decodeFromVideoDevice` that automatically stops the scanner after the first successful decode. It resolves with the decoded `Result` or rejects on unrecoverable errors.
```APIDOC
## BrowserCodeReader — decodeOnceFromVideoDevice()
### Description
Single-shot version of `decodeFromVideoDevice`. Resolves with the first successfully decoded `Result` and automatically stops the scanner. Rejects on unrecoverable errors (non-`NotFoundException`, non-`ChecksumException`, non-`FormatException`).
### Method
`async decodeOnceFromVideoDevice(deviceId: string | undefined, videoElement: HTMLVideoElement): Promise`
### Parameters
#### Path Parameters
None
#### Query Parameters
None
#### Request Body
None
### Request Example
```typescript
import { BrowserQRCodeReader } from '@zxing/browser';
const reader = new BrowserQRCodeReader();
try {
const result = await reader.decodeOnceFromVideoDevice(
undefined, // rear/environment camera
document.getElementById('preview') as HTMLVideoElement,
);
console.log('QR code content:', result.getText());
// e.g. "https://example.com"
} catch (err) {
console.error('Failed to decode:', err);
}
```
### Response
#### Success Response (Promise resolves with Result)
- **Result** (object) - The decoded result containing information about the scanned barcode.
#### Response Example
(See Request Example)
```
--------------------------------
### BrowserCodeReader.findDeviceById()
Source: https://context7.com/zxing-js/browser/llms.txt
Finds a specific video input device by its ID. This static convenience method first lists all available video input devices and then returns the `MediaDeviceInfo` object that matches the provided `deviceId`. If no device matches, it returns `undefined`.
```APIDOC
## BrowserCodeReader.findDeviceById()
### Description
Static convenience method that lists all video input devices and returns the `MediaDeviceInfo` entry matching the supplied `deviceId`, or `undefined` if not found.
### Method
`static async findDeviceById(deviceId: string): Promise`
### Example
```typescript
import { BrowserCodeReader } from '@zxing/browser';
const targetId = 'abc123...'; // previously stored device ID
const device = await BrowserCodeReader.findDeviceById(targetId);
if (device) {
console.log(`Found device: ${device.label}`);
} else {
console.warn('Device not found — it may have been disconnected.');
}
```
```
--------------------------------
### Create LuminanceSource from Canvas with HTMLCanvasElementLuminanceSource
Source: https://context7.com/zxing-js/browser/llms.txt
Implement a LuminanceSource using an HTMLCanvasElement, useful for custom decoding pipelines or when feeding pixel data to ZXing. Supports rotation and cropping of the canvas content.
```typescript
import { HTMLCanvasElementLuminanceSource } from '@zxing/browser';
import { BinaryBitmap, HybridBinarizer } from '@zxing/library';
const canvas = document.getElementById('frame') as HTMLCanvasElement;
// Assumes canvas already has image data drawn onto it
const luminanceSource = new HTMLCanvasElementLuminanceSource(canvas);
// Rotation support — useful for tilted barcodes
if (luminanceSource.isRotateSupported()) {
const rotated = luminanceSource.rotateCounterClockwise(); // rotate -90°
// or rotateCounterClockwise45() for -45°
}
// Crop to region of interest
const cropped = luminanceSource.crop(50, 50, 200, 200); // left, top, width, height
// Build a BinaryBitmap and decode manually
const bitmap = new BinaryBitmap(new HybridBinarizer(luminanceSource));
// Pass `bitmap` to any ZXing Reader.decode() call
```
--------------------------------
### BrowserCodeReader.decodeFromVideoDevice()
Source: https://context7.com/zxing-js/browser/llms.txt
Continuously scans for barcodes from a specified video device. It can optionally render the live video feed to a provided `