How to Build a Vanilla JavaScript Barcode Scanner with HTML5 and Dynamsoft SDK
The Dynamsoft Barcode Scanner JavaScript SDK (v10.5) is built on top of the Dynamsoft Capture Vision SDK, providing ready-to-use user interfaces and advanced APIs to simplify the development of web-based barcode scanner applications.
In this tutorial, you’ll learn how to:
- Integrate the SDK into your HTML5 + JavaScript app
- Scan 1D/2D barcodes from a live camera or a file (JPEG, PNG, or PDF)
What you’ll build: A vanilla JavaScript HTML5 barcode scanner web app that streams a live camera feed, scans 1D/2D barcodes in real time, and also reads barcodes from uploaded JPEG, PNG, and PDF files — all using the Dynamsoft Barcode Scanner SDK with no framework dependencies.
Key Takeaways
- The Dynamsoft Barcode Scanner SDK v10.5 provides a drop-in
BarcodeScannerclass that launches a fully functional camera-based scanner with a singlelaunch()call — no manual camera stream setup required. - The
onUniqueBarcodeScannedcallback andshowResultView: falseoption let you replace the built-in result panel with your own UI element while keeping the SDK’s camera logic intact. - Barcode reading from static image files is handled via
barcodeScanner.decode(blob), which accepts anyBlobincluding JPEG and PNG loaded with the FileReader API. - PDF barcode scanning requires first rasterizing the PDF to a JPEG using the Dynamsoft Document Viewer SDK (
DDV.Core.init()+saveToJpeg()), since the barcode scanner has no built-in PDF parser.
Common Developer Questions
- How do I add a JavaScript barcode scanner to a plain HTML5 web page without React or a framework?
- How do I read barcodes from a PDF file in the browser using JavaScript?
- How do I draw the barcode location bounding box on a canvas element after decoding?
Live Demo
Try the Online Barcode Scanner
Documentation
Dynamsoft Barcode Scanner Documentation
Online Barcode Generator
Use this online barcode generator to create 1D/2D barcodes for testing: https://yushulx.me/barcode-qrcode-generator/
Prerequisites
- License Key: Get a 30-day free trial.
-
JavaScript Barcode Scanner SDK: Include the dynamsoft-barcode-reader-bundle in your HTML page:
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader-bundle@10.5.3000/dist/dbr.bundle.js"></script> -
Dynamsoft Document Viewer: Include the Dynamsoft Document Viewer in your HTML page for PDF conversion.
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-document-viewer@2.1.0/dist/ddv.js"></script>
Step 1: Add a “Hello World” Barcode Scanner in 10 Lines
With just a few lines of JavaScript, you can quickly implement a fully functional barcode scanner in your web app.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dynamsoft Barcode Scanner</title>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-barcode-reader-bundle@10.5.3000/dist/dbr.bundle.js"></script>
</head>
<body>
<script>
const barcodeScannerConfig = {
license: "LICENSE-KEY",
scanMode: Dynamsoft.EnumScanMode.SM_MULTI_UNIQUE,
showResultView: true,
};
const barcodeScanner = new Dynamsoft.BarcodeScanner(barcodeScannerConfig);
(async () => {
const result = await barcodeScanner.launch();
})();
</script>
</body>
</html>
Replace LICENSE-KEY with your own license key, then run the code in your browser. The barcode scanner will open a camera view for scanning barcodes in real-time and display the results in a results panel.

Step 2: Embed the Barcode Scanner into a Custom HTML Container
Customizing the barcode scanner and embedding it into existing HTML elements is straightforward.
Follow the steps below to embed the barcode scanner into a custom HTML element:
-
Create a container element for the scanner.
#divScanner { border: 1px solid #ccc; transition: all 0.3s ease; } #container { width: 100%; height: 100%; }<div id="divScanner"> <div id="container"></div> </div> -
Instantiate the scanner object by specifying the
containerproperty.const container = document.getElementById("container"); const divScanner = document.getElementById("divScanner"); let BarcodeScanner = new Dynamsoft.BarcodeScanner({ license: licenseKey, container: container, }); function resizeScanner() { divScanner.style.width = window.innerWidth * 0.5 + "px"; divScanner.style.height = window.innerHeight * 0.5 + "px"; } resizeScanner();
Step 3: Handle Barcode Results in a Custom UI Element
In the Hello World example, you can’t handle barcode results until the launch() promise resolves. To instantly display the results in a custom UI element, you can use the onUniqueBarcodeScanned() callback and hide the default result view.
<textarea id="result" placeholder="Scan result will appear here..." readonly></textarea>
const resultArea = document.getElementById("result");
barcodeScanner = new Dynamsoft.BarcodeScanner({
license: licenseKey,
scanMode: Dynamsoft.EnumScanMode.SM_MULTI_UNIQUE,
container: container,
onUniqueBarcodeScanned: (result) => {
if (!result) {
resultArea.value = "No barcode found.\n";
}
else {
resultArea.value += "Text: " + result.text + "\n";
resultArea.value += "Format: " + result.formatString + "\n";
}
},
showResultView: false,
});
Step 4: Read Barcodes from Image Files and Highlight Locations on Canvas
The JavaScript Barcode Scanner SDK provides a decode() function to read barcodes from a single image file. The implementation is as follows:
- Load an image file as a
Bloband draw it on acanvaselement.#imageContainer { position: absolute; top: 0; left: 0; display: none; width: 100%; height: 100%; text-align: center; margin: 0; max-height: none; } #imageContainer canvas { max-width: 100%; max-height: 100%; object-fit: contain; }<input type="file" id="file" accept="image/png,image/jpeg,application/pdf" /> <div id="divScanner"> <div id="container"></div> <div id="imageContainer"></div> </div>document.getElementById("file").onchange = async function () { imageContainer.style.display = "none"; const files = Array.from(this.files || []); if (files.length) { try { let fileToProcess = files[0]; let blob = await readImage(fileToProcess); imageContainer.innerHTML = ""; const imageUrl = URL.createObjectURL(blob); const img = new Image(); img.onload = async function () { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = img.width; canvas.height = img.height; ctx.drawImage(img, 0, 0, canvas.width, canvas.height); imageContainer.appendChild(canvas); imageContainer.style.display = "block"; }; img.src = imageUrl; } catch (error) { console.error("Error processing file:", error); resultContainer.innerHTML = `<p>Error: ${error.message}</p>`; } } }; async function readImage(fileToProcess) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = async function (e) { try { const blob = new Blob([e.target.result], { type: fileToProcess.type }); resolve(blob); } catch (error) { reject(error); } }; reader.onerror = () => { reject(new Error("FileReader failed to read the file.")); }; reader.readAsArrayBuffer(fileToProcess); }); } -
Call
decode()function to detect barcodes from theblobobject.let blob = await readImage(fileToProcess); let result = await barcodeScanner.decode(blob); -
Display barcode results and draw barcode locations on the canvas.
if (!result || !result.barcodeResultItems) { resultArea.value = "No barcode found.\n"; } else { resultArea.value = ""; result.barcodeResultItems.forEach(item => { resultArea.value += "Text: " + item.text + "\n"; resultArea.value += "Format: " + item.formatString + "\n"; let localization = item.location; ctx.strokeStyle = '#ff0000'; ctx.lineWidth = 2; let points = localization.points; ctx.beginPath(); ctx.moveTo(points[0].x, points[0].y); ctx.lineTo(points[1].x, points[1].y); ctx.lineTo(points[2].x, points[2].y); ctx.lineTo(points[3].x, points[3].y); ctx.closePath(); ctx.stroke(); }); }
Step 5: Convert a PDF File to an Image and Read Its Barcodes
The JavaScript Barcode Scanner SDK doesn’t contain a built-in PDF rasterizer. To read barcodes from PDF files, you can first convert PDFs to images using the Dynamsoft Document Viewer.
-
Initialize the
Dynamsoft Document Viewerand create a document object.await Dynamsoft.DDV.Core.init(); currentDoc = Dynamsoft.DDV.documentManager.createDocument({ name: Date.now().toString(), author: "DDV", }); -
Load PDF files and save pages as JPEG images.
const reader = new FileReader(); reader.onload = async function (e) { try { const blob = new Blob([e.target.result], { type: fileToProcess.type }); const source = { fileData: blob, renderOptions: { renderAnnotations: "loadAnnotations" } }; currentDoc.deleteAllPages(); await currentDoc.loadSource([source]); const settings = { quality: 100, saveAnnotation: false, }; const image = await currentDoc.saveToJpeg(0, settings); resolve(image); } catch (error) { reject(error); } }; reader.onerror = () => { reject(new Error("FileReader failed to read the PDF file.")); }; reader.readAsArrayBuffer(fileToProcess); -
Update the
readImage()function to handle both images and PDFs.async function readImage(fileToProcess) { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = async function (e) { try { const blob = new Blob([e.target.result], { type: fileToProcess.type }); if (fileToProcess.type !== "application/pdf") { resolve(blob); return; } const source = { fileData: blob, renderOptions: { renderAnnotations: "loadAnnotations" } }; currentDoc.deleteAllPages(); await currentDoc.loadSource([source]); const settings = { quality: 100, saveAnnotation: false, }; const image = await currentDoc.saveToJpeg(0, settings); resolve(image); } catch (error) { reject(error); } }; reader.onerror = () => { reject(new Error("FileReader failed to read the PDF file.")); }; reader.readAsArrayBuffer(fileToProcess); }); }
Common Issues & Edge Cases
- Camera permission denied or no devices found: Browsers require a secure context (
https://orlocalhost) beforegetUserMediagrants camera access. Serving the page over plainhttp://will silently block the camera andlaunch()will throw. Always serve via HTTPS in production or uselocalhostfor local development. decode()returns no results on a valid image file: The Blob’s MIME type must match the actual file content — passing{ type: 'image/png' }for a JPEG will cause the SDK to misparse the header. Usefile.typedirectly from theFileobject rather than hardcoding the type string.- PDF pages after the first page are not scanned: The
saveToJpeg(0, settings)call in the PDF flow only rasterizes page index0. To scan a multi-page PDF, loop overcurrentDoc.getPageCount()and callsaveToJpeg(i, settings)for each page index, then calldecode()on each returned blob separately.
Source Code
https://github.com/yushulx/javascript-barcode-qr-code-scanner/tree/main/examples/barcode_scanner_rtu