wascan

Crates.iowascan
lib.rswascan
version0.1.10
created_at2025-11-24 19:10:42.615939+00
updated_at2026-01-11 10:42:00.76366+00
descriptionProduction-ready barcode and QR code scanner for web browsers. Handles camera access, streaming, and file input automatically.
homepage
repositoryhttps://github.com/intelligent-medical-cloud/pkg-wascan
max_upload_size
id1948431
size103,115
Dave (HrachMD)

documentation

README

wascan

npm crates.io license

A production-ready, plug-and-play WebAssembly barcode scanning library for the browser, built with Rust and wasm-bindgen. wascan handles all the complexity of camera access, streaming, and file input automatically - just integrate and start scanning.

Features

  • 🎯 Barcode & QR Code Scanning - By default only UPC-A and QR Code are included in the compiled wasm
  • 📷 Automatic Camera Handling - Camera access and streaming handled automatically with optimal configurations applied
  • 🖼️ Built-in File Input - File input field creation and handling managed by the library
  • 🌐 Universal Browser Support - Works on all modern browsers and platforms (iOS, Android, Safari, Chrome, Firefox, and Edge)
  • WebAssembly - Fast, native performance in the browser
  • 🚀 High Performance - Very high accuracy with low latency (typically under 0.2ms per detection)
  • 🔧 Easy Integration - Simple JavaScript API
  • 🎨 Demo Included - Try it out locally with the included demo

Installation

npm (Recommended for Web Projects)

npm install wascan

Or with yarn:

yarn add wascan

Or with pnpm:

pnpm add wascan

Cargo (Rust Projects)

Add this to your Cargo.toml:

[dependencies]
wascan = "0.1.10"

For JavaScript/TypeScript projects using npm, the package is ready to use. For Rust projects or custom builds, see the Build section below.

Usage

JavaScript/TypeScript

Basic Usage (Simple HTML/No Bundler)

import init, {
  init_reader,
  init_scanner,
  read_from_image,
  start_stream_scan,
  stop_stream_scan,
  on_detect,
  on_start,
  on_stop,
} from "wascan";

// Initialize the WASM module (automatic path resolution)
await init();

// Initialize the reader and scanner modules
init_reader();
init_scanner();

// Set up event callbacks
on_start(() => {
  console.log("Scanning started");
});

on_detect((result) => {
  if (result.success) {
    console.log("Detected:", result.value);
  } else {
    console.error("Error:", result.error);
  }
});

on_stop(() => {
  console.log("Scanning stopped");
});

// Start scanning from camera stream
start_stream_scan("video-element-id");

// Or trigger file input dialog to scan from image
read_from_image();

// Stop scanning programmatically
stop_stream_scan();

Usage with Bundlers (Vite, Webpack, etc.)

When using bundlers like Vite or Webpack, you may need to explicitly specify the WASM file path.

import init, {
  init_reader,
  init_scanner,
  read_from_image,
  start_stream_scan,
  stop_stream_scan,
  on_detect,
  on_start,
  on_stop,
} from "wascan";

// For Vite: Import WASM as URL
import wasmUrl from "wascan/wascan_bg.wasm?url";

// For other bundlers: Construct URL explicitly
const wasmUrl = new URL("wascan/wascan_bg.wasm", import.meta.url);

// Initialize with explicit WASM path (object format)
await init({ module_or_path: wasmUrl });

// ... rest of initialization code

Vue.js Example

import { onMounted, onBeforeUnmount } from "vue";
import init, {
  init_reader,
  init_scanner,
  start_stream_scan,
  stop_stream_scan,
  on_detect,
  on_start,
  on_stop,
} from "wascan";

// For Vite
import wasmUrl from "wascan/wascan_bg.wasm?url";

// For other bundlers
// const wasmUrl = new URL("wascan/wascan_bg.wasm", import.meta.url);

onMounted(async () => {
  try {
    await init({ module_or_path: wasmUrl });
    init_reader();
    init_scanner();

    on_start(() => console.log("Scanning started"));
    on_detect((result) => {
      if (result.success) {
        console.log("Detected:", result.value);
      }
    });
    on_stop(() => console.log("Scanning stopped"));

    start_stream_scan("video-element-id");
  } catch (error) {
    console.error("Failed to initialize:", error);
  }
});

onBeforeUnmount(() => {
  stop_stream_scan();
});

API

Initialization

  • init(module_or_path?) - Initializes the WASM module
    • Optional parameter: { module_or_path: string | URL } - Explicit path to WASM file
    • If not provided, automatically resolves to wascan_bg.wasm relative to the module
    • Returns a Promise that resolves when WASM is loaded
  • init_reader() - Initializes the reader module (required before using read_from_image)
  • init_scanner() - Initializes the scanner module (required before using start_stream_scan)

Scanning

  • start_stream_scan(video_element_id: &str) - Starts barcode scanning from camera stream
  • read_from_image() - Triggers file input dialog to scan from an image file
  • stop_stream_scan() - Stops the stream scanning

Event Callbacks

  • on_start(callback: Function) - Register callback for when scanning starts
  • on_detect(callback: Function) - Register callback for barcode detection
    • Callback receives: { success: boolean, value?: string, error?: string }
  • on_stop(callback: Function) - Register callback for when scanning stops

Supported Formats

wascan is built on top of the Rxing library (Rust port of ZXing), which supports a wide range of barcode formats. However, the built binary only includes UPC-A and QR Code to keep the WebAssembly bundle size minimal.

Formats Supported by Rxing/ZXing

The underlying Rxing library supports the following formats:

1D Product Barcodes:

  • UPC-A
  • UPC-E
  • EAN-8
  • EAN-13
  • DataBar (formerly RSS-14)
  • DataBar Limited

1D Industrial Barcodes:

  • Code 39
  • Code 93
  • Code 128
  • Codabar
  • DataBar Expanded
  • DX Film Edge
  • ITF (Interleaved Two of Five)

2D Matrix Barcodes:

  • QR Code
  • Micro QR Code
  • rMQR Code
  • Aztec
  • DataMatrix
  • PDF417
  • MaxiCode (partial support)

Currently Included in Built Binary

The pre-built wascan binary includes only:

  • UPC-A - Universal Product Code
  • QR Code - Quick Response Code

Adding More Formats

You can extend wascan to support additional barcode formats in two ways:

  1. Add specific readers explicitly - Modify src/detector.rs to include additional readers from the Rxing library (e.g., EAN13Reader, Code128Reader, DataMatrixReader, etc.)

  2. Use MultiReader - Replace the individual readers with rxing::MultiReader to support all formats at once

⚠️ Important: Including all barcode formats will approximately double the WASM bundle size. It's recommended to include only the formats required for your specific use case to keep the bundle size minimal.

Example of adding a specific reader:

use rxing::oned::EAN13Reader;

// Add EAN-13 detection alongside UPC-A and QR
let ean13_result = {
    let src = Luma8LuminanceSource::new(cropped.clone(), crop_w, crop_h);
    let binarizer = HybridBinarizer::new(src);
    let mut bitmap = BinaryBitmap::new(binarizer);
    let mut reader = EAN13Reader::default();
    reader.decode(&mut bitmap)
};

Performance

wascan delivers excellent performance characteristics:

  • High Accuracy - Very high detection accuracy for supported formats
  • Low Latency - Detection typically completes in under 0.2ms per frame
  • Optimized for Real-time - Efficient processing pipeline designed for continuous camera stream scanning

Benchmarks are not included in this repository, but users are welcome to measure performance on their own hardware and use cases. The WebAssembly implementation provides near-native performance while maintaining cross-platform compatibility.

Build

This crate is designed to be compiled to WebAssembly. Use the provided Makefile:

make build

This will generate ready to use WebAssembly files in the pkg/ directory.

Try the Demo

A working demo is included in the demo/ directory. To run it:

make demo
  • Navigate to http://localhost:8000/demo
  • Click "Start Stream Scan" to scan from your camera
  • Or click "Read From Image" to upload and scan an image file
  • Detected barcodes will appear in an alert and the browser console

Note: The demo uses the local pkg/ directory. For npm package usage examples, see the Usage section above.

Browser & Platform Support

wascan works seamlessly across all modern browsers and platforms:

  • Desktop: Chrome, Firefox, Safari, Edge
  • Mobile: iOS Safari, Chrome Android, Firefox Mobile
  • Tablets: iPad, Android tablets
  • WebAssembly: Required (supported by all modern browsers)

No platform-specific code needed - the library handles all browser differences automatically.

Requirements

  • Rust toolchain (for building from source)
  • wasm-bindgen-cli and wasm32-unknown-unknown for building WebAssembly packages (install via make init)
  • Python 3 (for the demo server, or use any static file server)
  • Modern browser with WebAssembly and WebRTC support (for camera functionality)

License

Licensed under the Apache License, Version 2.0. See LICENSE-APACHE for details.

This project builds upon the open-source Rxing project, which is also licensed under Apache 2.0.

Commit count: 52

cargo fmt