Skip to Content
DocsGetting Started

Quick Start

import React from 'react' import { BarcodeScanner } from 'react-barcode-scanner' import 'react-barcode-scanner/polyfill' export default () => { return ( <BarcodeScanner /> ) }

The example uses the included ZBar WASM polyfill. The installation guide lets you switch to the compatible ZXing WASM option.

Barcode format

BarcodeScanner scans qr_code by default. The formats option uses the standard format names  defined by the Barcode Detection API:

<BarcodeScanner options={{ formats: ['code_128'] }} />
⚠️

Available formats depend on the browser or polyfill BarcodeDetector implementation. Query BarcodeDetector.getSupportedFormats() at runtime, and see the installation options for the ZBar and ZXing differences.

Scanning delay

For performance, BarcodeScanner scans every 1000ms by default. Use the delay option for a shorter or longer interval:

<BarcodeScanner options={{ delay: 500 }} />

Torch

Use the useTorch hook to inspect support and control the camera torch:

import React from 'react' import { BarcodeScanner, useTorch } from 'react-barcode-scanner' export default () => { const { isTorchSupported, isTorchOn, setIsTorchOn } = useTorch() const onTorchSwitch = () => { setIsTorchOn(!isTorchOn) } return ( <div style={{ width: '100%', height: '360px' }}> <BarcodeScanner /> {isTorchSupported ? <button onClick={onTorchSwitch}>Switch Torch</button> : null} </div> ) }

Torch support depends on the browser and device. See MediaTrackConstraints .

State scope for Hooks

BarcodeScannerProvider defines which scanner state is read by scanner Hooks such as useStreamState() and useTorch(). It is useful for components that call these Hooks; BarcodeScanner also joins the same scope through its internal Hooks.

  • For one scanner, a Provider is optional. The scanner and Hooks share the default global scope.
  • If another component uses scanner Hooks, put it under the same Provider as the scanner.
  • For multiple active scanners, use one Provider per scanner so their streams and torch state stay separate.

The component that calls the Hooks must be inside the Provider:

import { BarcodeScanner, BarcodeScannerProvider, useStreamState, useTorch } from 'react-barcode-scanner' function ScannerPanel () { const [stream] = useStreamState() const { isTorchOn, setIsTorchOn } = useTorch() return ( <> <BarcodeScanner /> <p>Stream: {stream?.id ?? 'none'}</p> <button onClick={() => setIsTorchOn(!isTorchOn)}> Torch: {isTorchOn ? 'on' : 'off'} </button> </> ) } export default function App () { return ( <BarcodeScannerProvider> <ScannerPanel /> </BarcodeScannerProvider> ) }

When rendering multiple scanners, repeat this structure with a separate Provider for each ScannerPanel.

With framework

Next.js

The package can be imported during SSR, but the scanner itself uses browser APIs after mounting. Keep the Provider, scanner and external state consumers in the same Client Component:

ScannerPanel.tsx
'use client' import { BarcodeScanner, BarcodeScannerProvider } from 'react-barcode-scanner' import 'react-barcode-scanner/polyfill' export default function ScannerPanel () { return ( <BarcodeScannerProvider> <BarcodeScanner /> <ScannerControls /> </BarcodeScannerProvider> ) }

With the Pages Router, dynamically load the complete panel when you want to disable SSR for the scanner area:

import dynamic from 'next/dynamic' const ScannerPanel = dynamic( () => import('../components/ScannerPanel'), { ssr: false } )

With the App Router, the component that declares dynamic(..., { ssr: false }) must itself be a Client Component:

'use client' import dynamic from 'next/dynamic' const ScannerPanel = dynamic( () => import('./ScannerPanel'), { ssr: false } ) export default function ScannerPageClient () { return <ScannerPanel /> }
Last updated on