---
description: Unofficial Capacitor plugin to scan and decode barcodes, including QR codes and UPC codes, on Android, iOS, and Web.
title: ML Kit Barcode Scanning Plugin for Capacitor - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/announcing-the-capacitor-mlkit-barcode-scanner-plugin.png
---

[ Skip to content](#announcing-the-capacitor-ml-kit-barcode-scanning-plugin) 

[ 🎉 Introducing **Capawesome Platform** — one platform for Live Updates, Native Builds, App Store Publishing, and Insider SDKs.](https://capawesome.io) 

* [  Formbricks ](/docs/plugins/formbricks/)
* [  Geocoder ](/docs/plugins/geocoder/)
* [  Google Sign-In ](/docs/plugins/google-sign-in/)
* [  libSQL ](/docs/plugins/libsql/)
* [  Live Update ](/docs/plugins/live-update/)
* [  Managed Configurations ](/docs/plugins/managed-configurations/)
* [  Media Session ](/docs/plugins/media-session/)
* [  ML Kit ](/docs/plugins/mlkit/)
* [  NFC ](/docs/plugins/nfc/)
* [  OAuth ](/docs/plugins/oauth/)
* [  Pedometer ](/docs/plugins/pedometer/)
* [  Photo Editor ](/docs/plugins/photo-editor/)
* [  PostHog ](/docs/plugins/posthog/)
* [  Printer ](/docs/plugins/printer/)
* [  Purchases ](/docs/plugins/purchases/)
* [  RealtimeKit ](/docs/plugins/realtimekit/)
* [  Screen Orientation ](/docs/plugins/screen-orientation/)
* [  Screenshot ](/docs/plugins/screenshot/)
* [  Secure Preferences ](/docs/plugins/secure-preferences/)
* [  Speech Recognition ](/docs/plugins/speech-recognition/)
* [  Speech Synthesis ](/docs/plugins/speech-synthesis/)
* [  Share Target ](/docs/plugins/share-target/)
* [  Square Mobile Payments ](/docs/plugins/square-mobile-payments/)
* [  SQLite ](/docs/plugins/sqlite/)
* [  Superwall ](/docs/plugins/superwall/)
* [  Torch ](/docs/plugins/torch/)
* [  Wifi ](/docs/plugins/wifi/)
* [  Zip ](/docs/plugins/zip/)
* [  Cloud ](/docs/cloud/)
* [  Live Updates ](/docs/cloud/live-updates/)
* Advanced
* Integrations
* [  Native Builds ](/docs/cloud/native-builds/)
* [  Configuration ](/docs/cloud/native-builds/configuration/)
* [  Environments ](/docs/cloud/native-builds/environments/)
* Guides
* [  Sample Projects ](/docs/cloud/native-builds/sample-projects/)
* [  Troubleshooting ](/docs/cloud/native-builds/troubleshooting/)
* [  Automations ](/docs/cloud/automations/)
* [  Assist ](/docs/cloud/assist/)
* Account
* Organizations
* [  Organization and User Management ](/docs/cloud/organizations/memberships/)
* [  Single Sign-On (SSO) ](/docs/cloud/organizations/sso/)
* [  Teams ](/docs/cloud/organizations/teams/)
* [  Two-Factor Authentication ](/docs/cloud/organizations/two-factor-authentication/)
* [  Integrations ](/docs/cloud/integrations/)
* [  License Keys ](/docs/cloud/license-keys/)
* [  Webhooks ](/docs/cloud/webhooks/)
* [  Pricing ](https://capawesome.io/pricing/)
* [  FAQ ](/docs/cloud/faq/)
* [  Support ](/docs/cloud/support/)
* [  Contributing ](/docs/contributing/)
* [  LLMs ](/docs/llms/)
* [  Insiders ](/docs/insiders/)
* [  License ](https://capawesome.io/legal/eula/)
* [  Support ](/docs/insiders/support/)
* [  FAQ ](/docs/insiders/faq/)
* [  Blog ](/blog/)
* Categories

* [  Usage ](#usage)
* [  Demo App ](#demo-app)
* [  Closing Thoughts ](#closing-thoughts)

* Related links

# Announcing the Capacitor ML Kit Barcode Scanning Plugin[¶](#announcing-the-capacitor-ml-kit-barcode-scanning-plugin "Permanent link")

Today we are very excited to introduce you to the brand new [Capacitor ML Kit Barcode Scanning](/docs/plugins/mlkit/barcode-scanning/) plugin. This plugin is part of the new [Capacitor ML Kit](https://github.com/capawesome-team/capacitor-mlkit) project by Capawesome, which aims to bring the powerful [ML Kit SDKs](https://developers.google.com/ml-kit)[1](#fn:1) to Capacitor.

The plugin allows you to scan and decode various types of barcodes, including QR codes[2](#fn:2) and UPC codes. For a complete list of supported barcodes, see [BarcodeFormat](/docs/plugins/mlkit/barcode-scanning/#barcodeformat). The scanning is done directly on the device and does not require a network connection. The plugin supports Android and iOS, and it allows multiple barcodes to be scanned at once. It also has torch and autofocus support, and an optional ready-to-use interface without the need for webview customizations.

Demo App

Let's take a quick look at the [Barcode Scanning Plugin API](/docs/plugins/mlkit/barcode-scanning/#api) and how you can scan and decode barcodes.

## Installation[¶](#installation "Permanent link")

First you need to install the package and sync your Capacitor project:

`[](#%5F%5Fcodelineno-0-1)npm install @capacitor-mlkit/barcode-scanning
[](#%5F%5Fcodelineno-0-2)npx cap sync
`

### Android[¶](#android "Permanent link")

On Android, this plugin requires the following permissions be added to your `AndroidManifest.xml` (usually `android/app/src/main/AndroidManifest.xml`) before or after the `application` tag:

`[](#%5F%5Fcodelineno-1-1)<!-- To get access to the camera. -->
[](#%5F%5Fcodelineno-1-2)<uses-permission android:name="android.permission.CAMERA" />
[](#%5F%5Fcodelineno-1-3)<!-- To get access to the flashlight. -->
[](#%5F%5Fcodelineno-1-4)<uses-permission android:name="android.permission.FLASHLIGHT"/>
`

You also need to add the following meta data **in** the `application` tag in your `AndroidManifest.xml`:

`[](#%5F%5Fcodelineno-2-1)<meta-data android:name="com.google.mlkit.vision.DEPENDENCIES" android:value="barcode_ui"/>
`

### iOS[¶](#ios "Permanent link")

On iOS, add the `NSCameraUsageDescription` key to the `Info.plist` file (usually `ios/App/App/Info.plist`), which tells the user why the app needs to use the camera:

`[](#%5F%5Fcodelineno-3-1)<key>NSCameraUsageDescription</key>
[](#%5F%5Fcodelineno-3-2)<string>The app enables the scanning of various barcodes.</string>
`

If you also use `@capacitor-firebase/*` dependencies in your project, then implement [this workaround](https://github.com/capawesome-team/capacitor-mlkit/issues/23#issuecomment-1470739611) to avoid conflict with the Cocoapods dependencies.

## Usage[¶](#usage "Permanent link")

Let's see the plugin in action.

### Request permissions[¶](#request-permissions "Permanent link")

In order to be able to scan barcodes, we first need the camera permissions. We can easily request them via the plugin:

`[](#%5F%5Fcodelineno-4-1)import { BarcodeScanner } from "@capacitor-mlkit/barcode-scanning";
[](#%5F%5Fcodelineno-4-2)
[](#%5F%5Fcodelineno-4-3)const requestPermissions = async () => {
[](#%5F%5Fcodelineno-4-4)  await BarcodeScanner.requestPermissions();
[](#%5F%5Fcodelineno-4-5)};
`

In addition, you can use the method `isSupported()` to check whether the device has a camera:

`[](#%5F%5Fcodelineno-5-1)import { BarcodeScanner } from "@capacitor-mlkit/barcode-scanning";
[](#%5F%5Fcodelineno-5-2)
[](#%5F%5Fcodelineno-5-3)const isSupported = async () => {
[](#%5F%5Fcodelineno-5-4)  await BarcodeScanner.isSupported();
[](#%5F%5Fcodelineno-5-5)};
`

### Scan barcode with ready-to-use interface[¶](#scan-barcode-with-ready-to-use-interface "Permanent link")

Now that you have requested the permissions, you can scan your first barcode. To make the first scan as easy as possible and not require any WebView customization, you use the[scan()](/docs/plugins/mlkit/barcode-scanning/#scan) method, which provides a ready-to-use interface. By choosing a barcode format, we can improve the speed of the barcode scanner. In this example we are only looking for QR codes[2](#fn:2) and return the `rawValue` of the first QR code[2](#fn:2) found:

`[](#%5F%5Fcodelineno-6-1)import {
[](#%5F%5Fcodelineno-6-2)  BarcodeScanner,
[](#%5F%5Fcodelineno-6-3)  BarcodeFormat,
[](#%5F%5Fcodelineno-6-4)} from "@capacitor-mlkit/barcode-scanning";
[](#%5F%5Fcodelineno-6-5)
[](#%5F%5Fcodelineno-6-6)const scan = async () => {
[](#%5F%5Fcodelineno-6-7)  const { barcodes } = await BarcodeScanner.scan({
[](#%5F%5Fcodelineno-6-8)    formats: [BarcodeFormat.QrCode],
[](#%5F%5Fcodelineno-6-9)  });
[](#%5F%5Fcodelineno-6-10)  return barcodes[0].rawValue;
[](#%5F%5Fcodelineno-6-11)};
`

### Scan barcode with WebView customizations[¶](#scan-barcode-with-webview-customizations "Permanent link")

If you want to design the user interface yourself or scan several barcodes in a row, you need the methods [startScan(...)](/docs/plugins/mlkit/barcode-scanning/#startscan) and [stopScan()](/docs/plugins/mlkit/barcode-scanning/#stopscan). The camera is visible behind the WebView during scanning. However, this means that you have to hide all elements that should not be visible. In this case we set a class `barcode-scanning-active`, which then contains certain CSS rules (see below) for our app. You also need to add a [barcodeScanned](/docs/plugins/mlkit/barcode-scanning/#addlistenerbarcodescanned) listener so that you are notified of detected barcodes.

`` [](#%5F%5Fcodelineno-7-1)import { BarcodeScanner } from "@capawesome-team/capacitor-barcode-scanner";
[](#%5F%5Fcodelineno-7-2)
[](#%5F%5Fcodelineno-7-3)const startScan = async () => {
[](#%5F%5Fcodelineno-7-4)  // Hide all elements in the WebView
[](#%5F%5Fcodelineno-7-5)  document.querySelector("body")?.classList.add("barcode-scanning-active");
[](#%5F%5Fcodelineno-7-6)
[](#%5F%5Fcodelineno-7-7)  // Add the `barcodeScanned` listener
[](#%5F%5Fcodelineno-7-8)  const listener = await BarcodeScanner.addListener(
[](#%5F%5Fcodelineno-7-9)    "barcodeScanned",
[](#%5F%5Fcodelineno-7-10)    async (result) => {
[](#%5F%5Fcodelineno-7-11)      // Print the found barcode to the console
[](#%5F%5Fcodelineno-7-12)      console.log(result.barcode);
[](#%5F%5Fcodelineno-7-13)    },
[](#%5F%5Fcodelineno-7-14)  );
[](#%5F%5Fcodelineno-7-15)
[](#%5F%5Fcodelineno-7-16)  // Start the barcode scanner
[](#%5F%5Fcodelineno-7-17)  await BarcodeScanner.startScan();
[](#%5F%5Fcodelineno-7-18)};
[](#%5F%5Fcodelineno-7-19)
[](#%5F%5Fcodelineno-7-20)const stopScan = async () => {
[](#%5F%5Fcodelineno-7-21)  // Make all elements in the WebView visible again
[](#%5F%5Fcodelineno-7-22)  document.querySelector("body")?.classList.add("barcode-scanning-active");
[](#%5F%5Fcodelineno-7-23)
[](#%5F%5Fcodelineno-7-24)  // Remove all listeners
[](#%5F%5Fcodelineno-7-25)  await BarcodeScanner.removeAllListeners();
[](#%5F%5Fcodelineno-7-26)
[](#%5F%5Fcodelineno-7-27)  // Stop the barcode scanner
[](#%5F%5Fcodelineno-7-28)  await BarcodeScanner.stopScan();
[](#%5F%5Fcodelineno-7-29)};
 ``

An example of the CSS class `barcode-scanning-active` **with** Ionic could be:

`[](#%5F%5Fcodelineno-8-1)// Hide all elements
[](#%5F%5Fcodelineno-8-2)body.barcode-scanning-active {
[](#%5F%5Fcodelineno-8-3)  visibility: hidden;
[](#%5F%5Fcodelineno-8-4)  --background: transparent;
[](#%5F%5Fcodelineno-8-5)  --ion-background-color: transparent;
[](#%5F%5Fcodelineno-8-6)}
[](#%5F%5Fcodelineno-8-7)
[](#%5F%5Fcodelineno-8-8)// Show only the barcode scanner modal
[](#%5F%5Fcodelineno-8-9).barcode-scanning-modal {
[](#%5F%5Fcodelineno-8-10)  visibility: visible;
[](#%5F%5Fcodelineno-8-11)}
[](#%5F%5Fcodelineno-8-12)
[](#%5F%5Fcodelineno-8-13)@media (prefers-color-scheme: dark) {
[](#%5F%5Fcodelineno-8-14)  .barcode-scanning-modal {
[](#%5F%5Fcodelineno-8-15)    --background: transparent;
[](#%5F%5Fcodelineno-8-16)    --ion-background-color: transparent;
[](#%5F%5Fcodelineno-8-17)  }
[](#%5F%5Fcodelineno-8-18)}
`

An example of the CSS class `barcode-scanning-active` **without** Ionic could be:

`[](#%5F%5Fcodelineno-9-1)// Hide all elements
[](#%5F%5Fcodelineno-9-2)body.barcode-scanning-active {
[](#%5F%5Fcodelineno-9-3)  visibility: hidden;
[](#%5F%5Fcodelineno-9-4)}
[](#%5F%5Fcodelineno-9-5)
[](#%5F%5Fcodelineno-9-6)// Show only the barcode scanner modal
[](#%5F%5Fcodelineno-9-7).barcode-scanning-modal {
[](#%5F%5Fcodelineno-9-8)  visibility: visible;
[](#%5F%5Fcodelineno-9-9)}
`

Tip 

If you can't see the camera view, make sure **all elements** in the DOM are not visible or have a transparent background to debug the issue.

### Read barcode from image[¶](#read-barcode-from-image "Permanent link")

Last but not least, you have the option of scanning barcodes from an image you have already taken. All you need is the file path to the image. You can get the file path, for example, if the user selects an image using the [File Picker Plugin](/docs/plugins/file-picker/). The file path is passed to the method [readBarcodesFromImage(...)](/docs/plugins/mlkit/barcode-scanning/#readbarcodesfromimage), which then returns the detected barcodes:

`[](#%5F%5Fcodelineno-10-1)import {
[](#%5F%5Fcodelineno-10-2)  BarcodeScanner,
[](#%5F%5Fcodelineno-10-3)  BarcodeFormat,
[](#%5F%5Fcodelineno-10-4)} from "@capacitor-mlkit/barcode-scanning";
[](#%5F%5Fcodelineno-10-5)import { FilePicker } from "@capawesome/capacitor-file-picker";
[](#%5F%5Fcodelineno-10-6)
[](#%5F%5Fcodelineno-10-7)const pickImage = async () => {
[](#%5F%5Fcodelineno-10-8)  const { files } = await FilePicker.pickImages({
[](#%5F%5Fcodelineno-10-9)    multiple: true,
[](#%5F%5Fcodelineno-10-10)  });
[](#%5F%5Fcodelineno-10-11)  return files[0];
[](#%5F%5Fcodelineno-10-12)};
[](#%5F%5Fcodelineno-10-13)
[](#%5F%5Fcodelineno-10-14)const scan = async () => {
[](#%5F%5Fcodelineno-10-15)  const pickedImage = await pickImage();
[](#%5F%5Fcodelineno-10-16)  const { barcodes } = await BarcodeScanner.readBarcodesFromImage({
[](#%5F%5Fcodelineno-10-17)    formats: [BarcodeFormat.QrCode],
[](#%5F%5Fcodelineno-10-18)    path: pickedImage.path,
[](#%5F%5Fcodelineno-10-19)  });
[](#%5F%5Fcodelineno-10-20)  return barcodes[0].rawValue;
[](#%5F%5Fcodelineno-10-21)};
`

## Demo App[¶](#demo-app "Permanent link")

Feel free to download our [demo app](https://github.com/robingenz/capacitor-mlkit-plugin-demo) to see the plugin in action:

1. Clone the repository:  
`[](#%5F%5Fcodelineno-11-1)git clone https://github.com/robingenz/capacitor-mlkit-plugin-demo.git  
`
2. Change to the root directory:  
`[](#%5F%5Fcodelineno-12-1)cd capacitor-mlkit-plugin-demo  
`
3. Install all dependencies:  
`[](#%5F%5Fcodelineno-13-1)npm i  
`
4. Prepare and launch the Android app:  
`[](#%5F%5Fcodelineno-14-1)npx ionic cap sync android  
[](#%5F%5Fcodelineno-14-2)npx ionic cap run android  
`
5. Prepare and launch the iOS app:  
`[](#%5F%5Fcodelineno-15-1)npx ionic cap sync ios  
[](#%5F%5Fcodelineno-15-2)npx ionic cap run ios  
`

## Closing Thoughts[¶](#closing-thoughts "Permanent link")

Be sure to check out our [API Reference](/docs/plugins/mlkit/barcode-scanning/#api) to see what else you can do with this plugin. If you have any questions, just [create a discussion](https://github.com/capawesome-team/capacitor-mlkit/discussions/new/choose) in the [GitHub repository](https://github.com/capawesome-team/capacitor-mlkit). Make sure you follow us on [X](https://twitter.com/capawesomeio) so you don't miss any future updates. A big thank you to all the [sponsors](https://github.com/sponsors/capawesome-team) who make these projects possible!

---

1. This project is not affiliated with, endorsed by, sponsored by, or approved by Google LLC or any of their affiliates or subsidiaries. [↩](#fnref:1 "Jump back to footnote 1 in the text")
2. QR Code is a registered trademark of DENSO WAVE INCORPORATED. [↩](#fnref:2 "Jump back to footnote 2 in the text")[↩](#fnref2:2 "Jump back to footnote 2 in the text")[↩](#fnref3:2 "Jump back to footnote 2 in the text")

May 21, 2026 

 Back to top 