{"id":17707916,"url":"https://github.com/yudielcurbelo/react-qr-scanner","last_synced_at":"2026-01-20T01:08:33.181Z","repository":{"id":57170000,"uuid":"460915386","full_name":"yudielcurbelo/react-qr-scanner","owner":"yudielcurbelo","description":"A library to scan QR Codes in react.","archived":false,"fork":false,"pushed_at":"2025-02-26T23:15:16.000Z","size":68579,"stargazers_count":314,"open_issues_count":10,"forks_count":55,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-10T23:38:32.335Z","etag":null,"topics":["qr","qr-code","qrcode-reader","qrcode-scanner","react","reactjs","reader","scanner","typescript"],"latest_commit_sha":null,"homepage":"https://yudielcurbelo.github.io/react-qr-scanner/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yudielcurbelo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-18T15:58:52.000Z","updated_at":"2025-03-05T15:34:35.000Z","dependencies_parsed_at":"2023-11-07T17:32:26.624Z","dependency_job_id":"d10abad5-61e3-4d8a-85f8-3eb3f31ed58e","html_url":"https://github.com/yudielcurbelo/react-qr-scanner","commit_stats":{"total_commits":171,"total_committers":8,"mean_commits":21.375,"dds":0.1871345029239766,"last_synced_commit":"ef65b1e6ad2376b3b254ad0ddd28f828a68da2a9"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yudielcurbelo%2Freact-qr-scanner","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yudielcurbelo%2Freact-qr-scanner/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yudielcurbelo%2Freact-qr-scanner/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yudielcurbelo%2Freact-qr-scanner/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yudielcurbelo","download_url":"https://codeload.github.com/yudielcurbelo/react-qr-scanner/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243301127,"owners_count":20269286,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["qr","qr-code","qrcode-reader","qrcode-scanner","react","reactjs","reader","scanner","typescript"],"created_at":"2024-10-25T02:00:23.511Z","updated_at":"2026-01-20T01:08:33.175Z","avatar_url":"https://github.com/yudielcurbelo.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# @yudiel/react-qr-scanner\n\n[![npm version](https://img.shields.io/npm/v/@yudiel/react-qr-scanner.svg)](https://www.npmjs.com/package/@yudiel/react-qr-scanner)\n[![npm downloads](https://img.shields.io/npm/dm/@yudiel/react-qr-scanner.svg)](https://www.npmjs.com/package/@yudiel/react-qr-scanner)\n[![license](https://img.shields.io/npm/l/@yudiel/react-qr-scanner.svg)](https://github.com/yudielcurbelo/react-qr-scanner/blob/main/LICENSE)\n\nA modern React library for scanning QR codes and barcodes using your device camera or webcam. Built on top of the Barcode Detection API with React hooks and components.\n\n## Features\n\n- **Multiple Barcode Formats** - Supports QR codes, EAN, UPC, Code 128, and many more 1D/2D formats\n- **Camera Controls** - Built-in torch (flashlight), zoom, and camera switching capabilities\n- **Flexible Scanning** - Continuous scanning, single scan mode, or pause/resume functionality\n- **Custom Tracking** - Draw custom overlays and tracking visualizations on detected barcodes\n- **Device Selection** - Choose specific cameras with the `useDevices` hook\n- **Customizable UI** - Custom styles, class names, and component overrides\n- **Audio Feedback** - Optional beep sound on successful scans (with custom sound support)\n- **TypeScript Support** - Fully typed for excellent developer experience\n- **Lightweight** - Minimal dependencies with optimized bundle size\n- **Cross-browser Compatible** - Works across modern browsers with `webrtc-adapter`\n\n## Table of Contents\n\n- [Demo](#demo)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Usage Examples](#usage-examples)\n  - [Basic Scanner](#basic-scanner)\n  - [Device Selection](#device-selection)\n  - [Camera Constraints](#camera-constraints)\n  - [Custom Tracking Overlay](#custom-tracking-overlay)\n  - [Pausing and Resuming](#pausing-and-resuming)\n  - [UI Components](#ui-components)\n- [API Reference](#api-reference)\n  - [Scanner Props](#scanner-props)\n  - [useDevices Hook](#usedevices-hook)\n- [Supported Formats](#supported-formats)\n- [Type Definitions](#type-definitions)\n- [Browser Support](#browser-support)\n- [Limitations](#limitations)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Demo\n\nCheck out the [live demo](https://yudielcurbelo.github.io/react-qr-scanner/) to see the scanner in action.\n\n## Installation\n\n```bash\nnpm install @yudiel/react-qr-scanner\n```\n\n```bash\nyarn add @yudiel/react-qr-scanner\n```\n\n```bash\npnpm add @yudiel/react-qr-scanner\n```\n\n## Quick Start\n\n```jsx\nimport { Scanner } from '@yudiel/react-qr-scanner';\n\nfunction App() {\n  return (\n    \u003cScanner\n      onScan={(result) =\u003e console.log(result)}\n      onError={(error) =\u003e console.log(error?.message)}\n    /\u003e\n  );\n}\n```\n\n## Usage Examples\n\n### Basic Scanner\n\n```jsx\nimport { Scanner } from '@yudiel/react-qr-scanner';\n\nfunction BasicExample() {\n  const handleScan = (detectedCodes) =\u003e {\n    console.log('Detected codes:', detectedCodes);\n    // detectedCodes is an array of IDetectedBarcode objects\n    detectedCodes.forEach(code =\u003e {\n      console.log(`Format: ${code.format}, Value: ${code.rawValue}`);\n    });\n  };\n\n  return (\n    \u003cScanner\n      onScan={handleScan}\n      onError={(error) =\u003e console.error(error)}\n    /\u003e\n  );\n}\n```\n\n### Device Selection\n\nUse the `useDevices` hook to list available cameras and select a specific device:\n\n```jsx\nimport { Scanner, useDevices } from '@yudiel/react-qr-scanner';\nimport { useState } from 'react';\n\nfunction DeviceSelectionExample() {\n  const devices = useDevices();\n  const [selectedDevice, setSelectedDevice] = useState(null);\n\n  return (\n    \u003cdiv\u003e\n      \u003cselect onChange={(e) =\u003e setSelectedDevice(e.target.value)}\u003e\n        \u003coption value=\"\"\u003eSelect a camera\u003c/option\u003e\n        {devices.map((device) =\u003e (\n          \u003coption key={device.deviceId} value={device.deviceId}\u003e\n            {device.label || `Camera ${device.deviceId}`}\n          \u003c/option\u003e\n        ))}\n      \u003c/select\u003e\n\n      \u003cScanner\n        onScan={(result) =\u003e console.log(result)}\n        constraints={{\n          deviceId: selectedDevice,\n        }}\n      /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### Camera Constraints\n\nCustomize camera settings using MediaTrackConstraints:\n\n```jsx\nimport { Scanner } from '@yudiel/react-qr-scanner';\n\nfunction ConstraintsExample() {\n  return (\n    \u003cScanner\n      onScan={(result) =\u003e console.log(result)}\n      constraints={{\n        facingMode: 'environment', // Use rear camera\n        aspectRatio: 1, // Square aspect ratio\n        // Advanced constraints\n        width: { ideal: 1920 },\n        height: { ideal: 1080 },\n      }}\n    /\u003e\n  );\n}\n```\n\n### Custom Tracking Overlay\n\nDraw custom visualizations on detected barcodes:\n\n```jsx\nimport { Scanner } from '@yudiel/react-qr-scanner';\n\nfunction TrackingExample() {\n  const highlightCodeOnCanvas = (detectedCodes, ctx) =\u003e {\n    detectedCodes.forEach((detectedCode) =\u003e {\n      const { boundingBox, cornerPoints } = detectedCode;\n\n      // Draw bounding box\n      ctx.strokeStyle = '#00FF00';\n      ctx.lineWidth = 4;\n      ctx.strokeRect(\n        boundingBox.x,\n        boundingBox.y,\n        boundingBox.width,\n        boundingBox.height\n      );\n\n      // Draw corner points\n      ctx.fillStyle = '#FF0000';\n      cornerPoints.forEach((point) =\u003e {\n        ctx.beginPath();\n        ctx.arc(point.x, point.y, 5, 0, 2 * Math.PI);\n        ctx.fill();\n      });\n    });\n  };\n\n  return (\n    \u003cScanner\n      onScan={(result) =\u003e console.log(result)}\n      components={{\n        tracker: highlightCodeOnCanvas,\n      }}\n    /\u003e\n  );\n}\n```\n\n### Pausing and Resuming\n\nControl when the scanner is active:\n\n```jsx\nimport { Scanner } from '@yudiel/react-qr-scanner';\nimport { useState } from 'react';\n\nfunction PauseExample() {\n  const [isPaused, setIsPaused] = useState(false);\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={() =\u003e setIsPaused(!isPaused)}\u003e\n        {isPaused ? 'Resume' : 'Pause'} Scanning\n      \u003c/button\u003e\n\n      \u003cScanner\n        onScan={(result) =\u003e console.log(result)}\n        paused={isPaused}\n      /\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### UI Components\n\nEnable built-in UI controls for torch, zoom, and camera switching:\n\n```jsx\nimport { Scanner } from '@yudiel/react-qr-scanner';\n\nfunction UIComponentsExample() {\n  return (\n    \u003cScanner\n      onScan={(result) =\u003e console.log(result)}\n      components={{\n        audio: true, // Play beep sound on scan\n        onOff: true, // Show camera on/off button\n        torch: true, // Show torch/flashlight button (if supported)\n        zoom: true, // Show zoom control (if supported)\n        finder: true, // Show finder overlay\n      }}\n      // Custom sound (base64 encoded audio)\n      sound=\"data:audio/mp3;base64,YOUR_BASE64_AUDIO_HERE\"\n    /\u003e\n  );\n}\n```\n\n## API Reference\n\n### Scanner Props\n\n| Prop            | Type                                          | Required | Default | Description                                                                                      |\n|-----------------|-----------------------------------------------|----------|---------|--------------------------------------------------------------------------------------------------|\n| `onScan`        | `(detectedCodes: IDetectedBarcode[]) =\u003e void` | Yes      | -       | Callback function called when one or more barcodes are detected.                                 |\n| `onError`       | `(error: unknown) =\u003e void`                    | No       | -       | Callback function called when an error occurs while accessing the camera.                        |\n| `constraints`   | `MediaTrackConstraints`                       | No       | `{}`    | Media track constraints to apply to the video stream (e.g., `facingMode`, `deviceId`).          |\n| `formats`       | `BarcodeFormat[]`                             | No       | All     | Array of barcode formats to detect. If not specified, all supported formats are detected.        |\n| `paused`        | `boolean`                                     | No       | `false` | If `true`, the scanner pauses and displays the last frame.                                       |\n| `children`      | `ReactNode`                                   | No       | -       | Custom children to render inside the scanner container.                                          |\n| `components`    | `IScannerComponents`                          | No       | `{}`    | Configuration for built-in UI components and custom tracker function.                            |\n| `styles`        | `IScannerStyles`                              | No       | `{}`    | Custom CSS styles for scanner elements.                                                          |\n| `classNames`    | `IScannerClassNames`                          | No       | `{}`    | Custom CSS class names for scanner elements.                                                     |\n| `scanDelay`     | `number`                                      | No       | `500`   | Delay in milliseconds between successful scans. Prevents duplicate detections.                   |\n| `allowMultiple` | `boolean`                                     | No       | `false` | If `true`, allows the same barcode to trigger `onScan` multiple times.                           |\n| `sound`         | `boolean \\| string`                           | No       | `false` | If `true`, plays default beep sound. Provide a base64 audio string for custom sound.            |\n\n### useDevices Hook\n\nReturns an array of available video input devices (cameras).\n\n```typescript\nconst devices = useDevices();\n// Returns: MediaDeviceInfo[]\n```\n\n**Example:**\n\n```jsx\nimport { useDevices } from '@yudiel/react-qr-scanner';\n\nfunction CameraList() {\n  const devices = useDevices();\n\n  return (\n    \u003cul\u003e\n      {devices.map((device) =\u003e (\n        \u003cli key={device.deviceId}\u003e\n          {device.label || `Camera ${device.deviceId}`}\n        \u003c/li\u003e\n      ))}\n    \u003c/ul\u003e\n  );\n}\n```\n\n## Supported Formats\n\nThe library supports detection of the following barcode formats:\n\n| 1D Barcodes      | 2D Barcodes   |\n|------------------|---------------|\n| Codabar          | Aztec         |\n| Code 39          | Data Matrix   |\n| Code 93          | Matrix Codes  |\n| Code 128         | Maxi Code     |\n| Databar          | Micro QR Code |\n| Databar Expanded | PDF 417       |\n| Dx Film Edge     | QR Code       |\n| EAN 8            | rMQR Code     |\n| EAN 13           |               |\n| ITF              |               |\n| Linear Codes     |               |\n| UPC A            |               |\n| UPC E            |               |\n\nTo detect specific formats only:\n\n```jsx\n\u003cScanner\n  onScan={(result) =\u003e console.log(result)}\n  formats={['qr_code', 'ean_13', 'code_128']}\n/\u003e\n```\n\n## Type Definitions\n\n### `BarcodeFormat`\n\n```typescript\ntype BarcodeFormat =\n  | 'aztec'\n  | 'code_128'\n  | 'code_39'\n  | 'code_93'\n  | 'codabar'\n  | 'databar'\n  | 'databar_expanded'\n  | 'data_matrix'\n  | 'dx_film_edge'\n  | 'ean_13'\n  | 'ean_8'\n  | 'itf'\n  | 'maxi_code'\n  | 'micro_qr_code'\n  | 'pdf417'\n  | 'qr_code'\n  | 'rm_qr_code'\n  | 'upc_a'\n  | 'upc_e'\n  | 'linear_codes'\n  | 'matrix_codes'\n  | 'unknown';\n```\n\n### `IDetectedBarcode`\n\n```typescript\ninterface IDetectedBarcode {\n  boundingBox: IBoundingBox;\n  cornerPoints: IPoint[];\n  format: string;\n  rawValue: string;\n}\n```\n\n### `IBoundingBox`\n\n```typescript\ninterface IBoundingBox {\n  x: number;\n  y: number;\n  width: number;\n  height: number;\n}\n```\n\n### `IPoint`\n\n```typescript\ninterface IPoint {\n  x: number;\n  y: number;\n}\n```\n\n### `IScannerComponents`\n\n```typescript\ninterface IScannerComponents {\n  tracker?: TrackFunction;\n  onOff?: boolean;\n  torch?: boolean;\n  zoom?: boolean;\n  finder?: boolean;\n}\n```\n\n### `TrackFunction`\n\n```typescript\ntype TrackFunction = (\n  detectedCodes: IDetectedBarcode[],\n  ctx: CanvasRenderingContext2D\n) =\u003e void;\n```\n\n### `IScannerStyles`\n\n```typescript\ninterface IScannerStyles {\n  container?: CSSProperties;\n  video?: CSSProperties;\n  finderBorder?: number;\n}\n```\n\n### `IScannerClassNames`\n\n```typescript\ninterface IScannerClassNames {\n  container?: string;\n  video?: string;\n}\n```\n\n## Browser Support\n\nThis library requires support for:\n- **getUserMedia API** - Camera access\n- **Barcode Detection API** - Barcode scanning (polyfilled via [barcode-detector](https://www.npmjs.com/package/barcode-detector))\n- **Canvas API** - Drawing tracking overlays\n\n**Supported Browsers:**\n- Chrome/Edge 88+\n- Firefox 90+ (with polyfill)\n- Safari 14+ (with polyfill)\n- Mobile browsers (iOS Safari 14.5+, Chrome Mobile)\n\nThe library uses `webrtc-adapter` for cross-browser compatibility.\n\n## Limitations\n\n- **HTTPS or localhost required** - Due to browser security restrictions, camera access only works on secure contexts (HTTPS or localhost).\n- **iOS audio limitations** - Beep sound on iOS Safari requires user interaction before playing. The first scan after page load may not play sound.\n- **Server-Side Rendering (SSR)** - This library requires browser APIs and will not work during SSR. Ensure you only import and use it in client-side code:\n\n  ```jsx\n  // Next.js example\n  import dynamic from 'next/dynamic';\n\n  const Scanner = dynamic(\n    () =\u003e import('@yudiel/react-qr-scanner').then((mod) =\u003e mod.Scanner),\n    { ssr: false }\n  );\n  ```\n\n- **Mobile browser constraints** - Some mobile browsers cannot use torch and zoom simultaneously. The library automatically disables torch when zoom is activated to prevent conflicts.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add some amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\n[MIT](https://github.com/yudielcurbelo/react-qr-scanner/blob/main/LICENSE) © [Yudiel Curbelo](https://github.com/yudielcurbelo)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyudielcurbelo%2Freact-qr-scanner","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyudielcurbelo%2Freact-qr-scanner","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyudielcurbelo%2Freact-qr-scanner/lists"}