npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thewirv/react-barcode-scanner

v7.0.0

Published

A React component for scanning QR codes and other barcodes via webcam

Readme

React Barcode Scanner npm version License: MIT Known Vulnerabilities

React component for scanning barcodes from a camera.

Compatibility

Works in modern browsers.

Needs React 16.8+.

Uses the ZXing library and the same 1D and 2D formats. Older browsers need ZXing's compatibility notes.

File bugs at GitHub Issues.

Installation

bun add @thewirv/react-barcode-scanner
pnpm add @thewirv/react-barcode-scanner
yarn add @thewirv/react-barcode-scanner
npm i @thewirv/react-barcode-scanner

react-icons 4.9 or later is a peer. Install it if the app does not already have it.

Example usage

The preview is square and fills the parent width. The package JS imports dist/style.css. Those rules live in @layer react-barcode-scanner.

doScan={false} or a camera error swaps the video for the idle camera view. Until the stream has HAVE_ENOUGH_DATA, a loader covers the video.

import { useState } from "react";
import { BarcodeScanner } from "@thewirv/react-barcode-scanner";

function Test(props: Props) {
  let [data, setData] = useState("No result");

  return (
    <>
      <BarcodeScanner
        onSuccess={(text) => setData(text)}
        onError={(error) => {
          if (error) {
            console.error(error.message);
          }
        }}
        onLoad={() => console.log("Video feed has loaded!")}
      />
      <p>{data}</p>
    </>
  );
}

See the example app for a more complete integration than this snippet.

Theming

Set --rbs-* on any ancestor, or on .rbs:container through containerClassName.

Name react-barcode-scanner in your @layer list so later layers override the shipped rules. See disabling Preflight if using Tailwind CSS.

--rbs-aspect-ratio changes the layout box only. Default camera constraints stay square. object-fit: cover then crops a non-square frame. Set --rbs-video-object-fit if you want the whole frame.

Setting height on the container drops the ratio, because width is already filled. A user-facing camera also gets rbs:video-mirrored (scale: -1 1).

:root {
  --rbs-viewfinder-stroke: lime;
  --rbs-camera-off-border-color: #4f46e5;
}

| Custom property | Default | Applied on | | --------------------------------- | ------------------------------- | ------------------------------- | | --rbs-aspect-ratio | 1 | .rbs:container | | --rbs-width | 100% | .rbs:container | | --rbs-border-radius | 0 | .rbs:container | | --rbs-video-object-fit | cover | .rbs:video | | --rbs-viewfinder-stroke | rgba(255, 0, 0, 0.5) | .rbs:viewfinder | | --rbs-viewfinder-stroke-width | 3 | .rbs:viewfinder | | --rbs-viewfinder-overlay | rgba(0, 0, 0, 0.3) | .rbs:viewfinder-mask | | --rbs-camera-loading-background | rgba(0, 0, 0, 0.45) | .rbs:camera-loading | | --rbs-camera-loading-icon-color | #fff | .rbs:camera-loading-icon | | --rbs-camera-loading-icon-size | 72px | .rbs:camera-loading-icon | | --rbs-camera-off-border-width | 8px | .rbs:camera-off | | --rbs-camera-off-border-color | #eee | .rbs:camera-off | | --rbs-camera-off-border-radius | var(--rbs-border-radius, 5px) | .rbs:camera-off | | --rbs-camera-off-icon-size | 65% | .rbs:camera-off-icon | | --rbs-camera-off-icon-opacity | 0.2 | .rbs:camera-off-icon | | --rbs-camera-off-icon-color | currentColor | .rbs:camera-off-icon | | --rbs-flashlight-icon | #000 | .rbs:flashlight-toggle-button | | --rbs-flashlight-background | #fff | .rbs:flashlight-toggle-button |

Off, --rbs-flashlight-icon colors the icon and --rbs-flashlight-background colors the button. On, those two swap, and the button gets a box-shadow in the background color.

Component API

Scanning runs while doScan is true and no error has fired. After an error, set doScan false then true, pass constraint values that differ, or remount. A new constraints object with the same values does not retry.

| Prop | Type | Default | Description | | ------------------------------ | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | doScan | boolean | true | false unmounts <video> and shows camera-off | | constraints | MediaTrackConstraints | { facingMode: 'environment', width: { ideal: 720 }, height: { ideal: 720 }, aspectRatio: { ideal: 1 } } | Passed to getUserMedia. ideal so a camera without a square mode still opens. This prop replaces the whole default | | onSuccess | (text: string) => void | | Required. Called with the decoded text | | onError | (e?: Error) => void | | Required. Unmounts the video, stops the stream, and shows camera-off | | onLoad | () => void | | Called when the preview has HAVE_ENOUGH_DATA. The loader is then removed | | Viewfinder | React.ComponentType<{ className?: string; withCrosshairs: boolean }> \| null | built-in overlay | Rendered over the video after HAVE_ENOUGH_DATA. Pass null to hide it. The default overlay joins rbs:viewfinder with viewfinderClassName and draws crosshairs unless viewfinderCrosshairsDisabled is true | | containerClassName | string | | Appended after rbs:container | | videoContainerClassName | string | | Appended after rbs:video-container | | videoClassName | string | | Appended after rbs:video | | cameraLoadingClassName | string | | Appended after rbs:camera-loading | | cameraLoadingIconClassName | string | | Appended after rbs:camera-loading-icon | | cameraOffClassName | string | | Appended after rbs:camera-off | | cameraOffIconClassName | string | | Appended after rbs:camera-off-icon | | viewfinderClassName | string | | Passed to Viewfinder as className. The default overlay appends it after rbs:viewfinder | | viewfinderCrosshairsDisabled | boolean | | Passed to Viewfinder as withCrosshairs={!viewfinderCrosshairsDisabled}. The default overlay draws center crosshairs. true hides them. A custom component may use withCrosshairs or ignore it | | videoProps | VideoHTMLAttributes<HTMLVideoElement> or a function that receives those defaults | { playsInline: true, muted: true, disablePictureInPicture: true } | An object replaces the default video attributes. A function can extend them. Loaded-data handling stays with the library so the loader can clear | | flashlight | boolean \| FlashlightOptions | | Omit or false: no control. true: default button. An object sets class name, ARIA labels, and onError. Does not turn the lamp on. The button shows only when the track reports torch support |

FlashlightOptions fields are className, turnOnLabel (default "Turn flashlight on"), turnOffLabel (default "Turn flashlight off"), and onError. Off uses turnOnLabel. On uses turnOffLabel. The button also sets aria-pressed.

FlashlightOptions.onError receives a FlashlightError when the track has no usable torch, and when both applyConstraints shapes fail on a click or on a re-apply to a new stream. Import the codes from the package.

A click tries { advanced: [{ torch }] } then { torch }. The last on-toggle is kept across streams and re-applied to the next camera. The lamp turns off on stop, unmount, a constraint change, a decode error, and when flashlight is removed.

| Code | Meaning | | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | NO_TRACK | No video track was available when the library asked the camera about torch | | NO_GET_CAPABILITIES | The track has no getCapabilities method, so torch cannot be queried | | TORCH_MISSING | getCapabilities() returned no torch field | | TORCH_FALSE | getCapabilities() reported torch as false. This camera cannot turn a lamp on | | TORCH_SEQUENCE_INCOMPLETE | getCapabilities() reported a torch list that is not both true and false | | CONSTRAINT_APPLY_FAILED | Both applyConstraints shapes failed on a click or on a re-apply to a new stream. The library tried { advanced: [{ torch }] } then { torch } |

Migration

Upgrade to 7.0

7.0 draws center crosshairs on the built-in viewfinder. Pass viewfinderCrosshairsDisabled to hide them. The cutout is 15% inset so the corner marks sit on the edge. A custom Viewfinder receives withCrosshairs.

react-icons 4.9 or later is required.

flashlight is opt-in. The button appears only when the camera reports torch support.

Full notes are in the 7.0.0 changelog.

Upgrade to 6.0

6.0 drops containerStyle, videoContainerStyle, and videoStyle. Use *ClassName and --rbs-*.

Layout CSS is inside @layer react-barcode-scanner. rbs:video and videoClassName stay on the element even when videoProps is an object. videoProps.className is ignored.

A user-facing camera gets rbs:video-mirrored instead of an inline transform.

Full notes are in the 6.0.0 changelog.

Upgrade to 5.0

5.0 defaults the camera to a square preview: { facingMode: 'environment', width: { ideal: 720 }, height: { ideal: 720 }, aspectRatio: { ideal: 1 } }. Passing constraints replaces that whole default.

Viewfinder is a component or null. A React element no longer works. Omit it for the built-in overlay, or pass null to hide it.

Layout is CSS (dist/style.css), imported from the package JS. doScan={false} or a camera error unmounts the video and shows camera-off. A retry needs doScan toggled, different constraint values, or a remount.

Full notes are in the 5.0.0 changelog.

Upgrade to 4.0

4.0 is ESM-only. Use import { BarcodeScanner } from '@thewirv/react-barcode-scanner'. require() does not work, and the 3.x development / production export conditions are gone.

@zxing/browser is ^0.2.1 (was ^0.1.5). @zxing/library is ^0.23.0 (was ^0.21.3).

The camera session no longer restarts when parent callback identities change. The stream stops on unmount, doScan={false}, and constraint changes compared by value.

Full notes are in the 4.0.0 changelog.

License

Distributed under the MIT license. See LICENSE.