@cflorioluis/barcodereader
v0.1.0
Published
Dependency-free 1D/2D barcode & QR decoder. One Rust core, WASM for web (Angular/React/Vue/Electron/Capacitor), native FFI later.
Maintainers
Readme
BarCodeReader
A dependency-free 1D/2D barcode & QR decoder with one core that runs everywhere JavaScript runs — and, later, everywhere native FFI reaches.
The idea
The decoding logic is written once in pure Rust (core/). It knows nothing
about cameras, files or platforms: it takes a grayscale pixel buffer and returns
the decoded symbols. Every platform is a thin binding on top:
core (Rust, pure, no I/O)
decode_luma(pixels, width, height) -> Vec<Symbol>
│
├── wasm/ → wasm-pack → npm → Angular, React, Vue, Electron, Capacitor ← we are here
├── ffi/ → .so/.dll/.dylib (C ABI) → Flutter (dart:ffi), PHP (FFI), Python (step 2)
└── uniffi → Swift + Kotlin → native iOS / Android (step 3)Each platform only supplies pixels its own way (getUserMedia on web, AVFoundation on iOS, CameraX on Android). The hard part — finder patterns, perspective sampling, Reed-Solomon, payload decoding — lives in the core and is tested once.
Layout
| Path | What it is |
|------|-----------|
| core/ | Pure-Rust decoder. Image handling, binarization, QR pipeline. |
| wasm/ | wasm-bindgen wrappers → npm package (via wasm-pack). |
| js/ | Framework-agnostic camera glue + high-level BarcodeScanner. |
| docs/ | Integration guides (Angular, React, Capacitor, WASM bundling). |
| demo/ | Runnable apps: React, Angular, Capacitor (+ examples/web). |
| examples/web/ | Minimal browser demo driving the camera, zero build. |
| ROADMAP.md | Staged build plan and current status of each pipeline stage. |
Status
QR decoding works end-to-end from camera/image pixels: binarization (adaptive +
Otsu), finder detection, affine + perspective sampling, format info, Reed-Solomon,
and payload decode (numeric / alphanumeric / byte / ECI). Verified against
generated QR codes across versions 1–27, all EC levels, and a real photographed
thermal-receipt fixture. 1D symbologies and native FFI bindings are next — see
ROADMAP.md.
New here? Start with docs/getting-started.md.
Build (once the Rust toolchain is installed)
# 1. Toolchain (one-time)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install wasm-pack
# 2. Run core tests
cargo test -p barcode-core
# 3. Build the npm/WASM package
wasm-pack build wasm --target web --out-dir pkg
# → wasm/pkg/ is a ready-to-import ES module + .wasmThen import from any framework:
import { BarcodeScanner } from "@cflorioluis/barcodereader";
const scanner = new BarcodeScanner();
await scanner.start((r) => console.log(r.format, r.text)); // call from a clickPlatform notes
- iOS Safari: HTTPS (or localhost) + a user gesture to start.
playsinlineis set on the video element (required). - Android Chrome / desktop: works out of the box on HTTPS/localhost.
- Capacitor: runs in the WebView using the same WASM path.
- Electron: same WASM path (Chromium runtime).
