How to Build Web Barcode Scanner Using React and Webcam

Someone asked me how to create a real-time web barcode scanning app with a webcam. Is it hard to implement it? I’ve written an article sharing how to integrate Dynamsoft JavaScript Barcode Reader SDK into a React project. The remaining work is to make a webcam component.  Since there is an open source project called react-webcam, we don’t need to reinvent the wheel. In this article, I will share how to build a web barcode scanner step by step.

Camera-based Web Barcode Scanning Component

Download and open react-webcam.js.

Find render() function to add a button and a canvas. We use the button to trigger barcode scan and render barcode results on the canvas:

render() {
    return (
      <div id='videoview' width={this.props.width} height={this.props.height}>
        <button onClick={this.scanBarcode}>Scan Barcodes</button>
          ref={(ref) => {
   = ref;
        <canvas id="overlay" width={this.props.width} height={this.props.height}></canvas>

To show the results on the video, we need to adjust the styles of the HTML elements. Create a react-webcam.css file:

#videoview {
    position: relative;
    width: 640px;
    height: 480px;

#video {
    position: relative;
    width: 100%;
    height: 100%;
    z-index: 1

#overlay {
    position: absolute;
    top: 100;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 2

Import the CSS file in the react-webcam.js file:

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import './react-webcam.css';

Create a scanBarcode() function, in which we need to get the byte array of the video frame and then call the decodeBuffer() method:

scanBarcode() {
    if (window.reader) {
      let canvas = document.createElement('canvas');
      canvas.width = this.props.width;
      canvas.height = this.props.height
      let ctx = canvas.getContext('2d');
      ctx.drawImage(, 0, 0, this.props.width, this.props.height);
        ctx.getImageData(0, 0, canvas.width, canvas.height).data,
        canvas.width * 4,
      .then((results) => {

How to make the window.reader initialized? In public/index.html, create the instance of the barcode reader and make it globally accessible once the wasm file is loaded:

    <img src="loading.gif" style="margin-top:10px" id="anim-loading">
    <script src=""></script>
      dynamsoft.dbrEnv.resourcesPath = '';
      dynamsoft.dbrEnv.onAutoLoadWasmSuccess = function () {
        window.reader = new dynamsoft.BarcodeReader();
        window.dynamsoft = dynamsoft;
        document.getElementById('anim-loading').style.display = 'none';
      dynamsoft.dbrEnv.onAutoLoadWasmError = function (ex) {
        document.getElementById('anim-loading').style.display = 'none';
        alert('Fail to load the wasm file.');
      dynamsoft.dbrEnv.bUseWorker = true;

      // Get a free trial license from
      dynamsoft.dbrEnv.licenseKey = "Your Barcode SDK License"

    <div id="root"></div>

Note: dynamsoft.dbrEnv.bUseWorker has to be true. If we do not use web worker, the main thread will be heavily blocked.

To make this work in scanBarcode(), bind it in the constructor:

constructor() {
    this.state = {
      hasUserMedia: false,

    this.scanBarcode = this.scanBarcode.bind(this);

The following code shows how to continuously scan and show the barcode results on the webcam video:

showResults(results) {
    let context = this.clearOverlay();
    let txts = [];
    try {
      let localization;
      for (var i = 0; i < results.length; ++i) {
        if (results[i].LocalizationResult.ExtendedResultArray[0].Confidence >= 30) {
          localization = results[i].LocalizationResult;
          this.drawResult(context, localization, results[i].BarcodeText);
    } catch (e) {

clearOverlay() {
    let context = document.getElementById('overlay').getContext('2d');
    context.clearRect(0, 0, this.props.width, this.props.height);
    context.strokeStyle = '#ff0000';
    context.lineWidth = 5;
    return context;
drawResult(context, localization, text) {
    context.moveTo(localization.X1, localization.Y1);
    context.lineTo(localization.X2, localization.Y2);
    context.lineTo(localization.X3, localization.Y3);
    context.lineTo(localization.X4, localization.Y4);
    context.lineTo(localization.X1, localization.Y1);
    context.font = '18px Verdana';
    context.fillStyle = '#ff0000';
    let x = [ localization.X1, localization.X2, localization.X3, localization.X4 ];
    let y = [ localization.Y1, localization.Y2, localization.Y3, localization.Y4 ];
    x.sort(function(a, b) {
      return a - b;
    y.sort(function(a, b) {
      return b - a;
    let left = x[0];
    let top = y[0];
    context.fillText(text, left, top + 50);

Open App.js to add the React webcam component:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import {Barcode} from './Barcode';
import Webcam from './react-webcam';

class App extends Component {
  render() {
    return (
      <div className="App">
        <Webcam />

export default App;

Run the web barcode scanner app:

npm start

Visit localhost:3000:

react web barcode scanner with webcam

Source Code