How to Build a Web-Based JavaScript MRZ Passport Scanner and Reader
The Dynamsoft MRZ Scanner JavaScript SDK is a powerful, high-level wrapper built on top of the lower-level Dynamsoft Capture Vision API, designed to help developers add Machine Readable Zone (MRZ) recognition to any web application with ease. It is open-source and provides a clean and customizable API for scanning MRZ data from passports, ID cards, and visa documents using a web camera or by uploading images and PDFs.
In this tutorial, you’ll learn how to:
- Integrate the SDK into your HTML5 + JavaScript app
- Capture and parse MRZ data from multiple document types
- Display structured MRZ information
- Support both live camera input and file uploads (JPEG, PNG, PDF)
What you’ll build: A fully browser-based JavaScript MRZ passport scanner that reads MRZ data from passports, ID cards, and visas via live camera input or uploaded image/PDF files — powered by the Dynamsoft MRZ Scanner SDK.
Key Takeaways
- The Dynamsoft MRZ Scanner JavaScript SDK enables real-time MRZ recognition entirely in the browser, with no backend server required.
- The
MRZScanner.launch()method returns a structured result containing document type, name, nationality, birth date, expiry date, and raw MRZ text. - PDF files can be converted to JPEG client-side using Dynamsoft Document Viewer before MRZ processing — no server-side rendering needed.
- The SDK supports all three MRZ document formats: TD1 (ID cards), TD2 (visas), and TD3 (passports) through a single unified API.
Common Developer Questions
- How do I build a web-based MRZ passport reader in JavaScript?
- Can a JavaScript MRZ scanner run entirely in the browser without a backend?
- How do I read MRZ data from a PDF file in a web application?
This article is Part 2 in a 3-Part Series.
Demo: JavaScript MRZ Scanner
Live Demo
Documentation
Prerequisites
- License Key: Get a 30-day free trial.
-
JavaScript MRZ SDK: Include dynamsoft-mrz-scanner into your HTML page for MRZ scanning.
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-mrz-scanner@3.0.0/dist/mrz-scanner.bundle.js"></script> -
JavaScript PDF Reader: Include Dynamsoft Document Viewer into 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: Create a Hello World MRZ Scanner
The source code for the Dynamsoft MRZ Scanner is available on GitHub. The repository includes not only the full source code but also several sample projects to help you get started quickly.
Below is a basic Hello World example to launch the MRZ scanner in your browser:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dynamsoft MRZ Scanner - Hello World</title>
<script src="https://cdn.jsdelivr.net/npm/dynamsoft-mrz-scanner@3.0.0/dist/mrz-scanner.bundle.js"></script>
</head>
<body>
<h1 style="font-size: large">Dynamsoft MRZ Scanner</h1>
<script>
const mrzScanner = new Dynamsoft.MRZScanner({
license: "YOUR_LICENSE_KEY_HERE",
});
(async () => {
const result = await mrzScanner.launch();
})();
</script>
</body>
</html>
Replace YOUR_LICENSE_KEY_HERE with your own license key and run the code in your browser. The MRZ scanner provides a ready-to-use user interface with full functionality, so you can begin scanning MRZ right away without additional configuration.

Step 2: Embed the MRZ Scanner in a Custom HTML Element
By default, the MRZ scanner renders a full-screen camera view. If you want more control over the position and dimensions, you can bind the scanner to a specific HTML element like this:
#divScanner {
border: 1px solid #ccc;
transition: all 0.3s ease;
}
#container {
width: 100%;
height: 100%;
}
<div id="divScanner">
<div id="container"></div>
</div>
const container = document.getElementById("container");
const divScanner = document.getElementById("divScanner");
let mrzScanner = new Dynamsoft.MRZScanner({
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: Display Parsed MRZ Data with Image Preview
The launch() method returns a result object containing:
- The original image
- The raw MRZ string
- Parsed MRZ data fields
Here’s how to display them in a textarea and append the scanned image to the DOM:
<div id="divScanner">
<div id="container"></div>
<div id="imageContainer"></div>
</div>
<textarea id="result" placeholder="Scan result will appear here..." readonly></textarea>
const resultArea = document.getElementById("result");
function displayResult(result) {
resultArea.value = "";
imageContainer.innerHTML = "";
if (Object.keys(result.data).length !== 0) {
resultArea.value += "Document Type: " + result.data.documentType + "\n";
resultArea.value += "Document Number: " + result.data.documentNumber + "\n";
resultArea.value += "First Name: " + result.data.firstName + "\n";
resultArea.value += "Last Name: " + result.data.lastName + "\n";
resultArea.value += "Age: " + result.data.age + "\n";
resultArea.value += "Gender: " + result.data.sex + "\n";
resultArea.value += "Nationality: " + result.data.nationality + "\n";
resultArea.value += "Issuing State: " + result.data.issuingState + "\n";
resultArea.value += "Birth Date: " + result.data.dateOfBirth.day + "/" + result.data.dateOfBirth.month + "/" + result.data.dateOfBirth.year + "\n";
resultArea.value += "Expiry Date: " + result.data.dateOfExpiry.day + "/" + result.data.dateOfExpiry.month + "/" + result.data.dateOfExpiry.year + "\n\n";
resultArea.value += "MRZ Text: " + result.data.mrzText + "\n";
if (result.originalImageResult?.toCanvas) {
const originalImageCanvas = result.originalImageResult.toCanvas();
originalImageCanvas.style.maxWidth = "100%";
originalImageCanvas.style.height = "auto";
originalImageCanvas.style.objectFit = "contain";
imageContainer.appendChild(originalImageCanvas);
imageContainer.style.display = "block";
}
}
else
resultArea.value += "No MRZ data found.";
}
(async () => {
const result = await mrzScanner.launch();
displayResult(result);
})();

Step 4: Read MRZ from Uploaded Image Files
The MRZ scanner can also process files uploaded by the user. Supported formats include PNG and JPEG.
<input type="file" id="file" accept="image/png,image/jpeg,application/pdf" />
document.getElementById("file").onchange = async function () {
imageContainer.style.display = "none";
if (mrzScanner) {
const files = Array.from(this.files || []);
if (files.length) {
try {
let fileToProcess = files[0];
if (fileToProcess.type === "application/pdf") {
fileToProcess = await convertPDFToImage(fileToProcess);
}
const result = await mrzScanner.launch(fileToProcess);
displayResult(result);
} catch (error) {
console.error("Error processing file:", error);
resultContainer.innerHTML = `<p>Error: ${error.message}</p>`;
}
}
}
else {
resultArea.value = "Please activate the scanner first.\n";
}
};
Step 5: Convert PDF to JPEG for MRZ Scanning
The convertPDFToImage() function is not part of the MRZ Scanner SDK. You can implement it using some JavaScript PDF libraries like Dynamsoft Document Viewer.
Step 1: Initialize the Document Viewer
Initialize the Dynamsoft Document Viewer and instantiate a document object.
await Dynamsoft.DDV.Core.init();
currentDoc = Dynamsoft.DDV.documentManager.createDocument({
name: Date.now().toString(),
author: "DDV",
});
Step 2: Convert PDF to JPEG
Convert a PDF file to a blob encoded with JPEG format.
async function convertPDFToImage(pdfFile) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = async function (e) {
try {
const blob = new Blob([e.target.result], { type: pdfFile.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(pdfFile);
});
}
Common Issues & Edge Cases
- MRZ not detected from an uploaded image: Ensure the image is high resolution (at least 300 DPI equivalent) and the MRZ zone is fully visible and not cropped. Heavy JPEG compression degrades recognition accuracy.
- PDF conversion returns a blank image or fails silently:
Dynamsoft.DDV.Core.init()must fully resolve before callingcreateDocument(). Wrap both calls in a top-levelawaitinside an async IIFE and add atry/catchto surface the underlying error. - Scanner container has wrong dimensions after a browser resize or orientation change: Call your resize function both on page load and inside a
window.addEventListener('resize', ...)handler. Without the event listener, the container retains its initial size after the viewport changes on mobile.
Source Code
https://github.com/yushulx/javascript-barcode-qr-code-scanner/tree/main/examples/mrz_scanner_rtu