Decoding Barcodes with JavaScript Barcode Detection API
The Barcode Detection API provides web applications with the native ability to detect and decode linear and two-dimensional barcodes directly in the browser using JavaScript. By offloading processing tasks to underlying operating system features, this API enables high-performance, real-time barcode scanning without relying on heavy external third-party JavaScript libraries.
How the API Works
The Barcode Detection API operates via the native
BarcodeDetector interface, part of the broader Shape
Detection API specification. Instead of executing resource-intensive
pixel-parsing algorithms purely within the JavaScript engine, the
browser delegates image processing to native platform-level frameworks,
such as Google Play Services on Android, Core Image on macOS/iOS, or
Windows Media APIs. This architectural approach delivers faster
execution times, reduced battery consumption, and smaller web bundle
sizes.
Core Steps for Decoding Barcodes
Decoding barcodes with the API involves three primary steps: verifying feature availability and supported formats, initializing the detector, and passing an image source to the detection method.
1. Checking Format Support
Before attempting detection, verify that the browser supports the API and check which barcode types are available:
if ('BarcodeDetector' in window) {
const supportedFormats = await BarcodeDetector.getSupportedFormats();
console.log('Supported formats:', supportedFormats);
}Common supported formats include qr_code,
ean_13, ean_8, code_128,
code_39, upc_a, and
data_matrix.
2. Initializing the Detector
Create an instance of BarcodeDetector, optionally
specifying an array of barcode formats to optimize scanning speed:
const barcodeDetector = new BarcodeDetector({
formats: ['qr_code', 'ean_13', 'code_128']
});3. Processing Image Sources
The detect() method accepts any standard
ImageBitmapSource, such as an
HTMLImageElement, HTMLVideoElement,
HTMLCanvasElement, Blob, or
ImageData. The method runs asynchronously and returns a
promise resolving to an array of detected barcode objects:
async function scanSource(imageSource) {
try {
const barcodes = await barcodeDetector.detect(imageSource);
barcodes.forEach(barcode => {
console.log('Decoded Value:', barcode.rawValue);
console.log('Format:', barcode.format);
console.log('Bounding Box:', barcode.boundingBox);
console.log('Corner Points:', barcode.cornerPoints);
});
} catch (error) {
console.error('Detection failed:', error);
}
}Decoded Output Structure
Each item returned in the detection array contains:
rawValue: The decoded string content of the barcode.format: The detected barcode symbology (e.g.,'qr_code').boundingBox: ADOMRectReadOnlyobject outlining the coordinate boundaries (x,y,width,height) of the barcode within the source image.cornerPoints: An array of four coordinate points ({x, y}) specifying the exact polygon boundaries, enabling accurate visual overlays even if the barcode is skewed or rotated.
Real-Time Video Stream Scanning
For live camera feeds, the detect() method can be called
repeatedly inside a requestAnimationFrame() loop or
setInterval() timer, passing a live
<video> element connected to a
MediaStream from
navigator.mediaDevices.getUserMedia(). Because the
operation is asynchronous, processing frame-by-frame can occur without
blocking the main browser UI thread.