Building JavaScript and WebAssembly ZXing on Windows

If you are looking for a barcode SDK for web development, the ideal outcome is to find a pure JavaScript SDK. The pure JavaScript SDK means JavaScript APIs do not rely on any server-side code. However, most of the barcode SDKs are written in C/C++ and Java. They do not have corresponding JavaScript editions. Meanwhile, JavaScript performance is also the bottleneck. Nowadays, with the advent of WebAssembly, all this will change. WebAssembly runs alongside JavaScript, providing with near-native performance in modern web browsers. In this post, let’s see how to build JavaScript and WebAssembly ZXing — the most popular open source barcode SDK — for developing web barcode apps on Windows.

Emscripten Installation

Emscripten is an LLVM-to-JavaScript compiler, which converts C/C++ into JavaScript.

Download and unzip

Fetch the latest registry of available tools:

emsdk update

Download and install the latest SDK tools:

emsdk install latest

Make the “latest” SDK “active” for the current user:

emsdk activate latest

Activate PATH and other environment variables in the current terminal:


JavaScript ZXing

Clone the source code from GitHub. While following the steps to compile ZXing C++ code, I got some errors:

Check CMakeLists.txt to find which line caused the failure:

# Add libzxing library.
add_library(libzxing STATIC ${LIBZXING_FILES})
set_target_properties(libzxing PROPERTIES PREFIX "")

This part is to compile ZXing source code to a static library libzxing.bc. If I change STATIC to SHARED, the build will succeed.

I didn’t figure out how to fix this issue. My workaround is to skip the step and build the target zxing.js with ZXing source code directly. Here is the changed script:

# Add libzxing library.
# add_library(libzxing STATIC ${LIBZXING_FILES})
# set_target_properties(libzxing PROPERTIES PREFIX "")
# Add cli executable.
add_executable(zxing ${ZXING_FILES})
target_link_libraries(zxing libzxing)

Now I can successfully make zxing.js (1284K).

How to use zxing.js in web and Node.js apps?

There is a web app example test.html located at emscripten\test.

By studying the code, we can write a simple Node.js app.

To decode images in Node.js, you can use node-canvas. You must install all dependencies beforehand on Windows.
 Install node-canvas:

npm install canvas


const em_module = require('./zxing.js');
const ZXing = em_module();
const Canvas = require('canvas')
, Image = Canvas.Image;
const fs = require('fs');
fs.readFile(__dirname + '/Qr-10.png', function(err, squid){
if (err) throw err;
img = new Image;
img.src = squid;
let width = Math.floor(img.width), height = Math.floor(img.height);
let canvas = new Canvas(width, height);
let ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, width, height);
var imageData = ctx.getImageData(0, 0, width, height);
var idd =;
var decodeCallback = function (ptr, len, resultIndex, resultCount) {
var result = new Uint8Array(ZXing.HEAPU8.buffer, ptr, len);
console.log(String.fromCharCode.apply(null, result));
var decodePtr = ZXing.Runtime.addFunction(decodeCallback);
var image = ZXing._resize(width, height);
console.time("decode QR");
for (var i = 0, j = 0; i < idd.length; i += 4, j++) {
ZXing.HEAPU8[image + j] = idd[i];
var err = ZXing._decode_qr(decodePtr);
console.timeEnd('decode QR');
console.log("error code", err);

WebAssembly ZXing

To build WebAssembly, add a compiler parameter ‘-s WASM=1’. In the meantime, delete parameters ‘-s EXPORT_NAME=\”‘ZXing’\” -s MODULARIZE=1’ according to Emscripten compiling-to-JS parameters.

Edit CMakeLists.txt:

set(CMAKE_CXX_FLAGS "-std=c++11 --bind -Oz -s WASM=1 -s RESERVED_FUNCTION_POINTERS=20 -s DISABLE_EXCEPTION_CATCHING=0 --memory-init-file 0 -s EXPORTED_FUNCTIONS=\"['_resize','_decode_qr','_decode_qr_multi','_decode_any','_decode_multi']\"")

After successfully building the project, you can get zxing.js (154K) and zxing.wasm (566K). The two file size is much smaller than the single JavaScript file.

How to deploy WebAssembly to IIS?

Configure MimeType in web.config:

<?xml version="1.0" encoding="UTF-8"?>
<mimeMap fileExtension=".wasm" mimeType="application/wasm" />

Is your wasm file loaded?

Check it via developer tools:

Performance Comparison: JavaScript ZXing vs. WebAssembly ZXing

WebAssembly is the winner. Good news is that all major browsers now support WebAssembly.

Source Code

Originally published at on January 8, 2018.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.