Barcode Scanner
In-browser barcode and QR code reader. Nothing leaves your device — the decoder is gozxing (Go port of ZXing) compiled to WebAssembly. Your camera feed is processed locally frame-by-frame, never uploaded.
Scanner
tap Start, then tap on a barcode
loading wasm…
Tap the video to scan a specific region. Auto-scan runs in the background.
Supported formats
| Type | Formats |
|---|---|
| 2D | QR Code |
| 1D (product) | UPC-A, UPC-E, EAN-8, EAN-13 |
| 1D (industrial) | Code 128, Code 39, ITF |
How it works
- Camera — the browser's
getUserMediaAPI opens the rear camera. - Frame capture — every ~250 ms, the current video frame is drawn to an offscreen canvas and the RGBA pixel data is extracted.
- WASM decode — the pixel buffer is copied into the Go WASM module, which constructs a
BinaryBitmapand runs each reader (QR, EAN/UPC, Code 128, Code 39, ITF) until one matches. - Tap-to-scan — tapping the video crops a 40%-of-frame region around the tap point and decodes only that, reducing noise and speeding up detection.
- Result — decoded text is displayed and auto-copied to clipboard.
Privacy
Zero network requests after the page loads. The WASM binary and wasm_exec.js are static files served from this domain. Camera frames never leave the browser tab. There is no server-side component — the Go HTTP server in the source repo is only for local development.
Self-host / build from source
Source: git.nixc.us/colin/wasm-qr
git clone https://git.nixc.us/colin/wasm-qr.git
cd wasm-qr
make run
The Makefile compiles the WASM binary, copies wasm_exec.js from your Go installation, and starts an HTTPS server with a self-signed cert on :8443.
Limitations
- gozxing is less robust than native ZXing — works best with good lighting and a steady hand.
- iOS Safari and Chrome on mobile require HTTPS for camera access (this page is served over HTTPS).
- WASM binary is ~4 MB (first load only, then cached).