# Barcode Detection API (Shape Detection)

> BarcodeDetector detects supported linear and two-dimensional barcodes in image sources. This reference covers formats, results, input errors, and fallbacks.

The Barcode Detection API detects linear and two-dimensional barcodes in image sources. `BarcodeDetector.detect()` returns a promise containing `DetectedBarcode` values with the decoded `rawValue` and format. Results also expose a bounding box and corner points.

BCD records full support from Chrome for Android 83. Desktop Chromium support is platform-limited, Safari 17 exposes the interface behind the Shape Detection API preference, and Firefox is recorded as unsupported (BCD `api.BarcodeDetector`).

## Syntax

```js
new BarcodeDetector()
new BarcodeDetector(options)

BarcodeDetector.getSupportedFormats()
detector.detect(image)
```

The secure-context interface is exposed in windows and workers. `getSupportedFormats()` fulfills with the format names the user agent understands, while `detect()` fulfills with detected barcodes in the supplied image.

## Parameters

The constructor accepts one optional member.

| Member | Type | Meaning |
|---|---|---|
| `formats` | `string[]` | Limit later detections to the named barcode formats. If omitted, the user agent should search all supported formats. |

`detect(image)` accepts an `HTMLImageElement`, `SVGImageElement`, `HTMLVideoElement`, `HTMLCanvasElement`, `ImageBitmap`, or `OffscreenCanvas`. It also accepts a `VideoFrame` or image `Blob`, plus `ImageData`. Each result has `boundingBox` and `cornerPoints`, plus `format` and `rawValue`.

## Exceptions

The constructor throws `TypeError` when `formats` is empty or contains `"unknown"`. The [`detect()` algorithm](https://wicg.github.io/shape-detection-api/#image-sources-for-detection) (WICG) defines these failures.

| Exception | Condition |
|---|---|
| `TypeError` | No image is supplied, or its type is not an accepted image source. |
| `SecurityError` | The image has a different effective script origin, or a canvas is not origin-clean. |
| `InvalidStateError` | An `HTMLImageElement` is broken or not fully decoded, or a video's `readyState` is `HAVE_NOTHING` or `HAVE_METADATA`. |

:::caution
BCD records partial desktop support. Chrome 88 supports ChromeOS and macOS. Edge 83 and Opera 69 list macOS only. It also records that the interface silently failed before Chrome 113 on macOS Ventura 13 and later ([BCD `api.BarcodeDetector`](https://raw.githubusercontent.com/mdn/browser-compat-data/main/api/BarcodeDetector.json), MDN browser-compat-data).
:::

## Examples

Detect the constructor before creating it. A manual text field is a usable fallback when native barcode detection is absent.

### Scanning an image selected from disk

This snippet creates an image picker, a manual entry field, and an output element. Supported browsers scan the selected image `Blob`; other browsers leave the manual field enabled.

```js
const picker = document.body.appendChild(document.createElement("input"));
const manual = document.body.appendChild(document.createElement("input"));
const output = document.body.appendChild(document.createElement("p"));
picker.type = "file";
picker.accept = "image/*";
manual.placeholder = "Enter the barcode value";

if (!("BarcodeDetector" in globalThis)) {
  picker.disabled = true;
  output.textContent = "Automatic scanning is unavailable; enter the value manually.";
} else {
  const detector = new BarcodeDetector();
  picker.addEventListener("change", async () => {
    const [file] = picker.files;
    if (!file) return;
    const codes = await detector.detect(file);
    output.textContent = codes[0]?.rawValue ?? "No barcode detected";
  });
}
```

The fallback remains in the document even when the detector exists, so an empty detection result does not block manual entry.

### Requesting a format the platform supports

Check the user agent's format list before constructing a QR-code detector. Return `null` when either the interface or format is unavailable.

```js
async function createQrDetector() {
  if (!("BarcodeDetector" in globalThis)) return null;

  const formats = await BarcodeDetector.getSupportedFormats();
  if (!formats.includes("qr_code")) return null;
  return new BarcodeDetector({ formats: ["qr_code"] });
}

const detector = await createQrDetector();
if (!detector) console.info("Use the manual code field");
```

The caller can retain manual entry whenever the function returns `null`.

## See also

- [Screen Capture API](/reference/capabilities/screen-capture/), for obtaining frames from a display capture
- [Generic Sensor API](/reference/capabilities/sensors/), another secure-context device API
- [Accelerated Shape Detection in Images](https://wicg.github.io/shape-detection-api/#barcode-detection-api) (wicg.github.io)
- [Barcode Detection API](https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API) (MDN)