Migrating from other SDKs

Move to QRGen from html5-qrcode, @zxing/browser and @zxing/library, QuaggaJS and quagga2, or a commercial SDK such as Scandit, with side-by-side API and concept mappings.

Edit on GitHub

This page maps the APIs and concepts of popular barcode libraries to their QRGen equivalents, with before-and-after code. In most apps the migration is small: replace the scanner setup, rename the format constants to symbology ids, and read barcode.data instead of the old result’s text.

Install QRGen first:

npm install qrgen-sdk

Note: Until the first npm release is published, install the latest build with npm install https://rockyljewell.github.io/QR-GEN/downloads/qrgen-sdk.tgz.

From html5-qrcode

Pre-built scanner

Before:

import { Html5QrcodeScanner, Html5QrcodeSupportedFormats } from "html5-qrcode";

const scanner = new Html5QrcodeScanner(
  "reader",
  { fps: 10, qrbox: { width: 250, height: 250 }, formatsToSupport: [Html5QrcodeSupportedFormats.QR_CODE, Html5QrcodeSupportedFormats.EAN_13] },
  false
);
scanner.render(
  (decodedText, decodedResult) => console.log(decodedText, decodedResult.result.format.formatName),
  (errorMessage) => {} // called on every frame without a code
);

After:

<qrgen-scanner id="reader" symbologies="qr,ean13" style="height: 400px"></qrgen-scanner>

<script type="module">
  import "qrgen-sdk/elements";

  document.getElementById("reader").addEventListener("scan", ({ detail }) => {
    console.log(detail.barcode.data, detail.barcode.symbologyName);
  });
</script>

Camera API

Before:

import { Html5Qrcode } from "html5-qrcode";

const reader = new Html5Qrcode("reader");
await reader.start({ facingMode: "environment" }, { fps: 10, qrbox: 250 }, (text) => console.log(text));
// later
await reader.stop();

After:

import { BarcodeScanner } from "qrgen-sdk";

const scanner = new BarcodeScanner({ video: document.querySelector("video"), camera: "back", symbologies: ["qr"] });
scanner.on("scan", ({ barcodes }) => console.log(barcodes[0].data));
await scanner.start();
// later
scanner.stop();

Mapping

html5-qrcode QRGen
Html5QrcodeScanner(...).render(onSuccess) <qrgen-scanner> with a scan listener, or QRGenScanner in React
new Html5Qrcode(id).start(camera, config, onSuccess) new BarcodeScanner({ video, camera }).start() with scanner.on("scan", ...)
stop(), clear() stop(), destroy() (the element cleans up when removed)
pause(), resume() pause(), resume()
scanFile(file) scanImage(file), which returns every code in the image
Html5Qrcode.getCameras() Camera.list()
{ facingMode: "environment" } or a camera id camera: "back", "front" or a deviceId
formatsToSupport: [Html5QrcodeSupportedFormats.QR_CODE, ...] symbologies: ["qr", ...]
fps maxFps (default 24)
qrbox The element’s viewfinder sets the scan region automatically; scanArea for custom regions
decodedText barcode.data
decodedResult.result.format.formatName barcode.symbology (id) or barcode.symbologyName
Torch via getRunningTrackCameraCapabilities() setTorch(true), toggleTorch(), or the element’s torch button
Error callback on every frame Not needed; error fires only for real failures

Format names: QR_CODE is qr, DATA_MATRIX is data-matrix, EAN_13 is ean13, UPC_A is upca, CODE_128 is code128, CODE_39 is code39, ITF is itf, PDF_417 is pdf417, AZTEC is aztec, RSS_14 is databar, RSS_EXPANDED is databar-expanded.

From @zxing/browser and @zxing/library

@zxing/library is a JavaScript port of the Java ZXing library, and @zxing/browser adds camera helpers. QRGen uses zxing-cpp, a separate C++ implementation, compiled to WebAssembly and run in a Web Worker.

Before:

import { BrowserMultiFormatReader } from "@zxing/browser";
import { BarcodeFormat, DecodeHintType } from "@zxing/library";

const hints = new Map([
  [DecodeHintType.POSSIBLE_FORMATS, [BarcodeFormat.QR_CODE, BarcodeFormat.CODE_128]],
  [DecodeHintType.TRY_HARDER, true],
]);
const reader = new BrowserMultiFormatReader(hints);

const controls = await reader.decodeFromVideoDevice(undefined, "preview", (result, error) => {
  if (result) console.log(result.getText(), BarcodeFormat[result.getBarcodeFormat()]);
});
// later
controls.stop();

const fromImage = await reader.decodeFromImageUrl("/label.png");

After:

import { BarcodeScanner, scanImage } from "qrgen-sdk";

const scanner = new BarcodeScanner({ video: document.getElementById("preview"), symbologies: ["qr", "code128"], tryHarder: true });
scanner.on("scan", ({ barcodes }) => console.log(barcodes[0].data, barcodes[0].symbology));
await scanner.start();
// later
scanner.stop();

const fromImage = await scanImage("/label.png"); // an array; empty when nothing is found
@zxing/browser, @zxing/library QRGen
BrowserMultiFormatReader, BrowserQRCodeReader, … BarcodeScanner (one class for all formats)
decodeFromVideoDevice(deviceId, video, callback) new BarcodeScanner({ video, camera: deviceId }), on("scan"), start()
IScannerControls.stop() scanner.stop()
controls.switchTorch(on) scanner.setTorch(on)
BrowserMultiFormatReader.listVideoInputDevices() Camera.list()
decodeFromImageUrl, decodeFromImageElement, decodeFromCanvas scanImage(url | img | canvas)
decodeOnce... mode: "single"
DecodeHintType.POSSIBLE_FORMATS symbologies
DecodeHintType.TRY_HARDER tryHarder
NotFoundException for frames without a code No exception; an empty result or no scan event
result.getText() barcode.data
result.getBarcodeFormat() barcode.symbology
result.getResultPoints() barcode.location (four corners)
result.getRawBytes() fromBase64(barcode.rawBytes)
BrowserQRCodeSvgWriter, MultiFormatWriter generate(), generateSVG(), <qrgen-barcode>

From QuaggaJS and quagga2

Quagga reads linear (1D) barcodes. QRGen reads the same linear formats and adds QR, Data Matrix, PDF417 and the other 2D codes.

Before:

import Quagga from "@ericblade/quagga2";

Quagga.init(
  {
    inputStream: { type: "LiveStream", target: document.querySelector("#scanner"), constraints: { facingMode: "environment" } },
    decoder: { readers: ["ean_reader", "upc_reader", "code_128_reader"] },
    locate: true,
  },
  (err) => {
    if (err) return console.error(err);
    Quagga.start();
  }
);
Quagga.onDetected((data) => console.log(data.codeResult.code, data.codeResult.format));
// later
Quagga.stop();

After:

<qrgen-scanner id="scanner" symbologies="ean13,upca,code128" style="height: 400px"></qrgen-scanner>

<script type="module">
  import "qrgen-sdk/elements";

  const scanner = document.getElementById("scanner");
  scanner.addEventListener("scan", ({ detail }) => console.log(detail.barcode.data, detail.barcode.symbology));
  // later: scanner.stop(), or remove the element
</script>
Quagga QRGen
Quagga.init(config, cb) and Quagga.start() Add <qrgen-scanner> (starts automatically), or new BarcodeScanner(options).start()
Quagga.stop() stop()
Quagga.onDetected(cb) scan event
Quagga.onProcessed(cb) frame event on BarcodeScanner (every decoded frame)
Quagga.decodeSingle({ src }) scanImage(src)
inputStream.constraints camera, resolution
inputStream.area scanArea (normalized 0 to 1)
locate: true Always on; codes are found anywhere in the scan area, at any angle
frequency maxFps
numOfWorkers Decoding runs in a Web Worker automatically
data.codeResult.code barcode.data
data.codeResult.format barcode.symbology
data.box, data.line barcode.location

Reader names:

Quagga reader QRGen id
ean_reader ean13
ean_8_reader ean8
upc_reader upca
upc_e_reader upce
code_128_reader code128
code_39_reader, code_39_vin_reader code39
code_93_reader code93
codabar_reader codabar
i2of5_reader itf
code_32_reader code32
2of5_reader (Standard 2 of 5) Not supported

Quagga apps often filter results by error rate or wait for several identical reads before accepting a code. QRGen’s engine verifies check digits and symbol structure, so you can usually remove those heuristics. If you still see misreads, limit symbologies to what you actually scan.

From Scandit and other commercial SDKs

Note: QRGen is an independent open-source project. It is not affiliated with, endorsed by or sponsored by Scandit AG. Scandit, SparkScan and MatrixScan are trademarks of Scandit AG. Product names below are used only to describe equivalent concepts.

Commercial SDKs such as Scandit are built around similar concepts: a capture mode that recognizes barcodes in camera frames, a camera abstraction, overlays and viewfinders, and settings for symbologies, duplicates and feedback. The table maps these concepts to QRGen. API names differ between Scandit SDK versions and platforms, so check their documentation for the exact names in your version.

Scandit concept QRGen equivalent
License key and data capture context None. No key, no account, no activation.
Camera and frame source on/off scanner.start(), scanner.stop()
Barcode capture (single-barcode scanning) Continuous mode (mode="continuous", the default) with the scan event
Disabling capture temporarily pause() and resume()
Barcode capture settings: enabled symbologies symbologies (ids)
Code duplicate filter duplicateFilter (ms; 0 and -1 behave as in Core concepts)
Location selection (restricting the scan area) scanArea, or automatic from the element’s viewfinder
Rectangular and laserline viewfinders viewfinder="frame" and viewfinder="line"
Capture feedback (sound, vibration) beep, vibrate, scanner.feedback
SparkScan (pre-built scanning UI) <qrgen-scanner>, QRGenScanner in React and Vue, the embed page in WebViews
MatrixScan (tracking many barcodes, “BarcodeBatch”, previously “BarcodeTracking”) Batch mode (mode="batch") with track events and TrackedBarcode ids; BarcodeTracker for custom pipelines
MatrixScan basic overlay (highlights on tracked codes) Built into <qrgen-scanner> in batch mode, or your own canvas: see UI customization
Choose tracked codes The element’s accessible results list, select event and selection
ID capture (AAMVA barcode) parseAAMVA() on a scanned PDF417
ID capture (MRZ, visual inspection zone, OCR) Not available
Barcode generator generate(), <qrgen-barcode>
Parsers (GS1, AAMVA, and others) parseContent(), parseGS1(), parseAAMVA()
Barcode result: data, symbology, location, GS1 flag barcode.data, barcode.symbology, barcode.location, barcode.isGS1

Symbology names: an EAN-13/UPC-A setting corresponds to ean13 and upca (QRGen lists them separately; enable both), QR to qr, Data Matrix to data-matrix, Code 128 to code128, PDF417 to pdf417, Interleaved 2 of 5 to itf, GS1 DataBar to databar, databar-expanded and databar-limited.

A typical “scan a barcode, look up the product” flow in QRGen:

<qrgen-scanner id="scanner" symbologies="ean13,upca,upce,code128" duplicate-filter="2000" style="height: 60vh"></qrgen-scanner>

<script type="module">
  import "qrgen-sdk/elements";
  import { parseContent } from "qrgen-sdk";

  document.getElementById("scanner").addEventListener("scan", ({ detail }) => {
    const content = parseContent(detail.barcode.data, { symbology: detail.barcode.symbology });
    if (content.type === "product") console.log("Look up GTIN", content.gtin);
  });
</script>

Before you switch

Be realistic about the trade-offs:

  • Recognition performance. Commercial SDKs invest heavily in computer vision. They may still outperform QRGen on badly damaged, blurry or very small codes, at long distances, in poor lighting, at steep angles and on low-end devices. Test QRGen with your real codes, devices and conditions before switching.
  • Features. QRGen doesn’t include OCR, MRZ reading, AR overlays beyond highlights, or item counting and search workflows as ready-made products. You can build some of these on batch mode and your own UI.
  • Support. QRGen is community supported through GitHub. There is no SLA.

In return you get an Apache-2.0 licensed SDK with no license keys, per-device fees or telemetry, on-device processing, and the same API across the web, Node.js, Python and native platforms.

Esc

Share this page

Migrating from other SDKs · Docs | QRGen

Star QRGen on GitHub Add a "Powered by QRGen" badge