If you’re building cross-platform mobile apps with Capacitor, chances are you’ll need a way to read barcodes at some point—whether you’re processing inventory, enabling contactless checkouts, or scanning event tickets. As a Capacitor solution provider, we work with teams every week who get stuck trying to implement barcode scanning without native code bloat or fragile workarounds. Today I’m walking you through a straightforward, production-ready method that avoids common pitfalls and works seamlessly across iOS, Android, and the web. Capacitor

First, let’s cut through the noise: there’s no need to dive into Swift or Kotlin for basic barcode scanning in a Capacitor app. The easiest path is to use a well-maintained Capacitor plugin that wraps native platform APIs and exposes a simple JavaScript interface. The gold standard here is the capacitor-barcode-scanner plugin, but I’ve also tested others and will share what to look for when choosing one (hint: maintainer activity and support for all Capacitor versions matter more than flashy extra features).
Before you dive into code, make sure your project is set up for success. We recommend working with Capacitor 5 or newer—older versions have outdated plugin compatibility and more platform configuration hurdles. Start by installing the plugin via npm: run npm install @capacitor-community/barcode-scanner followed by npx cap sync to link it to your native iOS and Android projects. If you’re using Capacitor 6, double-check the plugin’s version matches your Capacitor core; mismatched versions are the top cause of “barcode scanner not working on iOS” errors we see in client tickets.
Next, you’ll need to request camera permissions. This is non-negotiable—iOS and Android both block camera access at the OS level if you don’t ask for it properly, and users hate broken permissions. The plugin includes a helper method to handle this, so you don’t have to write native permission code yourself. On Android, you’ll need to add a single line to your AndroidManifest.xml if you’re targeting API 33 or higher, but the capacitor-barcode-scanner plugin usually adds this automatically during npx cap sync. For iOS, you’ll need to add a camera usage description to your Info.plist—something like “Need camera access to scan barcodes” so users understand why you’re requesting access, which makes them more likely to grant it.
Now for the actual scanning logic. Let’s walk through a simple example that works in any Capacitor frontend (React, Vue, Angular, or even vanilla JS). First, import the plugin:
import { BarcodeScanner } from '@capacitor-community/barcode-scanner';
Then, write an async function to check permissions and start the scanner. We use async/await here because all plugin methods are promise-based:
async function startScanner() {
// Check existing permission status
const permissionStatus = await BarcodeScanner.checkPermission({ force: true });
if (permissionStatus.granted) {
// Hide the app background to make the scanner full-screen
document.body.style.background = 'transparent';
document.body.querySelector('main').style.display = 'none';
// Start the scanner and listen for scanned codes
const scanResult = await BarcodeScanner.startScan();
if (scanResult.hasContent) {
console.log('Scanned barcode:', scanResult.content);
// Do something with the result—e.g., update state, submit to an API
alert(`Barcode found: ${scanResult.content}`);
}
// Reset the app UI after scanning finishes
document.body.style.background = '';
document.body.querySelector('main').style.display = '';
} else if (permissionStatus.denied) {
// If permission is permanently denied, prompt the user to enable it in settings
alert('Please enable camera access in your device settings to scan barcodes.');
} else {
// Request permission if it hasn’t been granted yet
await BarcodeScanner.requestPermission();
// Retry scanning after permission is granted
startScanner();
}
}
I’ve used this exact flow in dozens of client projects, and it avoids common mistakes like leaving the scanner running in the background (which drains battery) or blocking the user’s main app UI. The startScan method also supports multiple barcode formats—if you only need to scan UPC-A for inventory or QR codes for tickets, you can specify a formats option to limit scanning speed: await BarcodeScanner.startScan({ formats: ['qr_code'] }). That’s a huge win for performance; scanning only QR codes is faster and less error-prone than scanning all 1D and 2D formats.
Wait—what about the web? If you’re testing your app in a browser before deploying to mobile, the barcode scanner works there too! The plugin falls back to the browser’s built-in MediaDevices API when running on the web, so you can test scanning on your desktop without setting up emulators. Just note that web testing will only work over HTTPS (or localhost for development), so you can’t test it on plain HTTP. We usually run npm run build and use npx cap serve to test the web portion locally, which works every time.
Now, let’s talk about common gotchas we run into as a Capacitor provider. The first big one is memory leaks: if you leave the scanner running after the user scans a code or navigates away, it will drain the device’s battery and may crash low-end phones. Always call BarcodeScanner.stopScan() when you’re done, and add a cleanup function if you’re using a framework like React or Vue: in a React component, return a useEffect cleanup that stops the scan if the component unmounts.
Another common issue is orientation locks. On iOS, if your app is locked to portrait mode, the scanner view may stretch or misalign. We’ve fixed this in client projects by adding a small adjustment to the native iOS scanner view, or by explicitly setting the scanner’s orientation to match the device when it starts. The capacitor-barcode-scanner plugin exposes a setOrientation method that makes this easy.
For Android users, if you’re targeting API 34 (Android 14), you’ll need to add the CAMERA permission to your AndroidManifest.xml manually if it’s not already there. The plugin usually handles this during sync, but sometimes custom build configs can override it. Just add <uses-permission android:name="android.permission.CAMERA" /> right after the application tag in your manifest, and you’ll be good to go.
What if you need advanced features? Like scanning barcodes in a modal instead of full-screen, or integrating with a custom backend to validate barcodes in real time? The capacitor-barcode-scanner plugin lets you customize the scanner’s UI, or you can pair it with a library like zxing-wasm for even more control over barcode processing. We’ve built custom barcode scanning flows for retail clients that scan thousands of codes per minute, and combining the Capacitor plugin with a lightweight WASM-based decoder works perfectly for high-volume use cases.
Let’s test this flow end-to-end, because the last thing you want is to write code that works on your emulator but fails on a real device. After you’ve written the scanning function, run npx cap sync to push the updated code to your native projects, then open the iOS project in Xcode or the Android project in Android Studio. Run the app on a physical device (emulators often have limited camera access and slower scanning) and test scanning a physical barcode or a QR code on your phone. If it works, great—you’re done. If not, check the plugin’s GitHub issues; 90% of common problems are documented there, and the Capacitor community is fast about fixing bugs.
As a Capacitor solution provider, we’ve found that the best barcode scanning implementations balance simplicity, performance, and cross-platform compatibility. You don’t need to rewrite your entire app in native code to get reliable scanning—using a well-maintained Capacitor plugin is the sweet spot that cuts development time and keeps your codebase consistent across all platforms.

If you’re building a Capacitor app and want to implement barcode scanning, or if you need help troubleshooting platform-specific issues, optimizing performance for high-volume scanning, or customizing your scanner UI to match your brand, we’re here to help. We work with teams of all sizes, from startups building their first mobile app to enterprise clients with complex inventory and checkout systems, and we tailor our solutions to your specific needs. Reach out to our team to discuss your project, and we’ll walk you through the best approach for your Capacitor app.
Capacitor References:
Capacitor Community Barcode Scanner Plugin Documentation
Official Capacitor Permissions Guide
Apple Developer: iOS Camera Usage Description
Android Developer: Manifest Permissions for Camera API
Jingdezhen Wanping Electric Co., Ltd.
As one of the most professional capacitor manufacturers and suppliers in China, we also support customized service. We warmly welcome you to buy high quality capacitor made in China here and get pricelist from our factory. For price consultation, contact us.
Address: Zhangshukeng, Jingdezhen City, Jiangxi Province.
E-mail: jdzwpdq0815@163.com
WebSite: https://www.cewpdq.com/