---
description: Create a cross-platform barcode scanner app using Ionic Framework and Capacitor with ML Kit Barcode Scanning.
title: How to Build an Ionic Barcode Scanner with Capacitor - Capawesome
image: https://capawesome.io/docs/assets/images/social/blog/how-to-build-an-ionic-barcode-scanner-with-capacitor.png
---

[ Skip to content](#how-to-build-an-ionic-barcode-scanner-with-capacitor) 

[ 🎉 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

* [  Add the Barcode Scanner ](#add-the-barcode-scanner)
* [  Run the App ](#run-the-app)
* [  Conclusion ](#conclusion)

* Related links

# How to Build an Ionic Barcode Scanner with Capacitor[¶](#how-to-build-an-ionic-barcode-scanner-with-capacitor "Permanent link")

Capacitor makes building a cross-platform app with one codebase easier than ever before. In combination with the Ionic Framework, we also have a modern open source mobile UI toolkit. We will use these technologies to create a complete barcode scanner app for Android and iOS in just 15 minutes.

Highlights include:

* One Angular codebase that runs on Android and iOS using Capacitor.
* Barcode Scanning functionality powered by ML Kit, Google’s machine learning SDK for Android and iOS.

Find the complete app code referenced in this guide [on GitHub](https://github.com/robingenz/ionic-capacitor-barcode-scanner).

![Capacitor Barcode Scanner Demo](/blog/how-to-build-an-ionic-barcode-scanner-with-capacitor/228339891-4b251e8f-95d5-4865-b74b-5ded07ba9fe7.gif) 

Capacitor Barcode Scanner Demo

## Download Required Tools[¶](#download-required-tools "Permanent link")

Download and install the following tools to ensure an optimal developer experience:

* [Node.js](https://nodejs.org/en/download) to install the required dependencies
* A code editor for... writing code! **Tip**: Visual Studio Code supports the new [Ionic VS Code Extension](https://ionicframework.com/docs/intro/vscode-extension)
* [Android Studio](https://developer.android.com/studio) to build the Android app
* [Xcode](https://apps.apple.com/de/app/xcode/id497799835) to build the iOS app (only available on macOS)

## Create a new App[¶](#create-a-new-app "Permanent link")

To create a new project, we simply use the Ionic CLI. For this, first install the CLI globally:

`[](#%5F%5Fcodelineno-0-1)npm i -g @ionic/cli
`

Then you can create a new project with the `ionic start` command:

`[](#%5F%5Fcodelineno-1-1)npx ionic start barcode-scanner blank --type=angular --capacitor
`

In this case, the app is called `barcode-scanner`, the starter template is `blank` and the project type for the purposes of this guide is Angular. You can also choose Vue or React, for example. Additionally, we enable the Capacitor integration with `--capacitor`.

Once everything is ready, you should see this output:

`[](#%5F%5Fcodelineno-2-1)Your Ionic app is ready! Follow these next steps:
[](#%5F%5Fcodelineno-2-2)
[](#%5F%5Fcodelineno-2-3)- Go to your new project: cd .\barcode-scanner
[](#%5F%5Fcodelineno-2-4)- Run ionic serve within the app directory to see your app in the browser
[](#%5F%5Fcodelineno-2-5)- Run ionic capacitor add to add a native iOS or Android project using Capacitor
[](#%5F%5Fcodelineno-2-6)- Generate your app icon and splash screens using cordova-res --skip-config --copy
[](#%5F%5Fcodelineno-2-7)- Explore the Ionic docs for components, tutorials, and more: https://ion.link/docs
[](#%5F%5Fcodelineno-2-8)- Building an enterprise app? Ionic has Enterprise Support and Features: https://ion.link/enterprise-edition
`

### Add the Android Platform[¶](#add-the-android-platform "Permanent link")

Now let's add the Android platform.

For this, first install the `@capacitor/android` package:

`[](#%5F%5Fcodelineno-3-1)npm install @capacitor/android
`

After that you add the platform:

`[](#%5F%5Fcodelineno-4-1)npx cap add android
`

### Add the iOS Platform[¶](#add-the-ios-platform "Permanent link")

Install the `@capacitor/ios` package:

`[](#%5F%5Fcodelineno-5-1)npm install @capacitor/ios
`

After that you add the platform:

`[](#%5F%5Fcodelineno-6-1)npx cap add ios
`

## Add the Barcode Scanner[¶](#add-the-barcode-scanner "Permanent link")

### Install the Plugin[¶](#install-the-plugin "Permanent link")

To use the ML Kit Barcode Scanning SDK in Capacitor, we need to install the [Capacitor ML Kit Barcode Scanning](/docs/plugins/mlkit/barcode-scanning/) plugin:

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

On Android, the SDKs also require the following permissions in the `AndroidManifest.xml` before or after the `application` tag:

android/app/src/main/AndroidManifest.xml

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

android/app/src/main/AndroidManifest.xml

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

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

ios/App/App/Info.plist

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

The plugin is now ready to use.

### Build the UI[¶](#build-the-ui "Permanent link")

Scanning a barcode is as simple as it gets: You just have to call the [scan(...)](/docs/plugins/mlkit/barcode-scanning/#scan) method of the plugin and receive the scanned barcode as a result. To request the necessary permissions and to show the user a dialog in case of missing permissions, we will also use the [requestPermissions()](/docs/plugins/mlkit/barcode-scanning/#requestpermissions) method.

The following code goes to your `src/app/home/home.page.ts`:

| src/app/home/home.page.ts                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [ 1](#%5F%5Fcodelineno-11-1) [ 2](#%5F%5Fcodelineno-11-2) [ 3](#%5F%5Fcodelineno-11-3) [ 4](#%5F%5Fcodelineno-11-4) [ 5](#%5F%5Fcodelineno-11-5) [ 6](#%5F%5Fcodelineno-11-6) [ 7](#%5F%5Fcodelineno-11-7) [ 8](#%5F%5Fcodelineno-11-8) [ 9](#%5F%5Fcodelineno-11-9) [10](#%5F%5Fcodelineno-11-10) [11](#%5F%5Fcodelineno-11-11) [12](#%5F%5Fcodelineno-11-12) [13](#%5F%5Fcodelineno-11-13) [14](#%5F%5Fcodelineno-11-14) [15](#%5F%5Fcodelineno-11-15) [16](#%5F%5Fcodelineno-11-16) [17](#%5F%5Fcodelineno-11-17) [18](#%5F%5Fcodelineno-11-18) [19](#%5F%5Fcodelineno-11-19) [20](#%5F%5Fcodelineno-11-20) [21](#%5F%5Fcodelineno-11-21) [22](#%5F%5Fcodelineno-11-22) [23](#%5F%5Fcodelineno-11-23) [24](#%5F%5Fcodelineno-11-24) [25](#%5F%5Fcodelineno-11-25) [26](#%5F%5Fcodelineno-11-26) [27](#%5F%5Fcodelineno-11-27) [28](#%5F%5Fcodelineno-11-28) [29](#%5F%5Fcodelineno-11-29) [30](#%5F%5Fcodelineno-11-30) [31](#%5F%5Fcodelineno-11-31) [32](#%5F%5Fcodelineno-11-32) [33](#%5F%5Fcodelineno-11-33) [34](#%5F%5Fcodelineno-11-34) [35](#%5F%5Fcodelineno-11-35) [36](#%5F%5Fcodelineno-11-36) [37](#%5F%5Fcodelineno-11-37) [38](#%5F%5Fcodelineno-11-38) [39](#%5F%5Fcodelineno-11-39) [40](#%5F%5Fcodelineno-11-40) [41](#%5F%5Fcodelineno-11-41) [42](#%5F%5Fcodelineno-11-42) [43](#%5F%5Fcodelineno-11-43) [44](#%5F%5Fcodelineno-11-44) [45](#%5F%5Fcodelineno-11-45) | import { Component, OnInit } from "@angular/core"; import { Barcode, BarcodeScanner } from "@capacitor-mlkit/barcode-scanning"; import { AlertController } from "@ionic/angular"; @Component({   selector: "app-home",   templateUrl: "home.page.html",   styleUrls: \["home.page.scss"\], }) export class HomePage implements OnInit {   isSupported \= false;   barcodes: Barcode\[\] \= \[\];   constructor(private alertController: AlertController) {}   ngOnInit() {     BarcodeScanner.isSupported().then((result) \=> {       this.isSupported \= result.supported;     });   }   async scan(): Promise<void\> {     const granted \= await this.requestPermissions();     if (!granted) {       this.presentAlert();       return;     }     const { barcodes } \= await BarcodeScanner.scan();     this.barcodes.push(...barcodes);   }   async requestPermissions(): Promise<boolean\> {     const { camera } \= await BarcodeScanner.requestPermissions();     return camera \=== "granted" \|| camera \=== "limited";   }   async presentAlert(): Promise<void\> {     const alert \= await this.alertController.create({       header: "Permission denied",       message: "Please grant camera permission to use the barcode scanner.",       buttons: \["OK"\],     });     await alert.present();   } } |

To make the scanning process even faster and to reduce the error rate even further, you could filter on the formats you are looking for (e.g. QR codes[1](#fn:1)) using the `formats` option. However, we leave this up to you.

Last but not least, the only thing missing is the template. To keep the app simple, we just list all scanned barcodes with [ion-list](https://ionicframework.com/docs/api/list). The scanning process is started via a floating action button in the bottom right corner.

For this, change your `src/app/home/home.page.html` to:

| src/app/home/home.page.html                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [ 1](#%5F%5Fcodelineno-12-1) [ 2](#%5F%5Fcodelineno-12-2) [ 3](#%5F%5Fcodelineno-12-3) [ 4](#%5F%5Fcodelineno-12-4) [ 5](#%5F%5Fcodelineno-12-5) [ 6](#%5F%5Fcodelineno-12-6) [ 7](#%5F%5Fcodelineno-12-7) [ 8](#%5F%5Fcodelineno-12-8) [ 9](#%5F%5Fcodelineno-12-9) [10](#%5F%5Fcodelineno-12-10) [11](#%5F%5Fcodelineno-12-11) [12](#%5F%5Fcodelineno-12-12) [13](#%5F%5Fcodelineno-12-13) [14](#%5F%5Fcodelineno-12-14) [15](#%5F%5Fcodelineno-12-15) [16](#%5F%5Fcodelineno-12-16) [17](#%5F%5Fcodelineno-12-17) [18](#%5F%5Fcodelineno-12-18) [19](#%5F%5Fcodelineno-12-19) | <ion-header\>   <ion-toolbar\>     <ion-title\>Barcode Scanner</ion-title\>   </ion-toolbar\> </ion-header\> <ion-content\>   <ion-list\>     <ion-item \*ngFor\="let barcode of barcodes"\>       <ion-label position\="stacked"\>{{ barcode.format }}</ion-label\>       <ion-input type\="text" \[value\]="barcode.rawValue"\></ion-input\>     </ion-item\>   </ion-list\>   <ion-fab slot\="fixed" vertical\="bottom" horizontal\="end"\>     <ion-fab-button (click)="scan()" \[disabled\]="!isSupported"\>       <ion-icon name\="scan"\></ion-icon\>     </ion-fab-button\>   </ion-fab\> </ion-content\> |

Now everything is ready for the first launch! 🎉

## Run the App[¶](#run-the-app "Permanent link")

Run the app and scan your first barcode or QR code[1](#fn:1):

`[](#%5F%5Fcodelineno-13-1)# Run the Android platform
[](#%5F%5Fcodelineno-13-2)npx ionic cap run android
[](#%5F%5Fcodelineno-13-3)
[](#%5F%5Fcodelineno-13-4)# Run the iOS platform
[](#%5F%5Fcodelineno-13-5)npx ionic cap run ios
`

That was easy, wasn't it?

## Conclusion[¶](#conclusion "Permanent link")

Implementing a barcode scanner across multiple platforms can be challenging. However, the Capacitor ML Kit barcode scanning plugin does most of the work for you and the performance of the ML Kit SDK is quite impressive. Only the Web platform is not supported by Google's machine learning SDK. If you also want to support the Web platform, you can just combine this plugin with other libraries like [zxing-js/library](https://github.com/zxing-js/library) or the [Barcode Detection API](https://developer.mozilla.org/en-US/docs/Web/API/Barcode%5FDetection%5FAPI) (still experimental).

Be sure to check out the [API Reference](https://github.com/capawesome-team/capacitor-mlkit/tree/main/packages/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. Make sure you follow [Capawesome](https://twitter.com/capawesomeio) on X so you don't miss any future updates.

---

---

1. `QR Code` is a registered trademark of DENSO WAVE INCORPORATED. [↩](#fnref:1 "Jump back to footnote 1 in the text")[↩](#fnref2:1 "Jump back to footnote 1 in the text")

March 18, 2026 

 Back to top 