For a new Flutter app that needs to scan QR codes or barcodes, start with mobile_scanner. It is the practical default for Android, iOS, macOS, and web projects, but it is not a Linux or Windows camera solution. Choose something else when you need a different platform, direct ML Kit access, a ready-made scanner UI, or compatibility with an existing QRView-based app.
Maintenance status changes the recommendation. qr_code_scanner is now marked as maintenance-only, and its author points new projects toward mobile_scanner. That makes it a migration consideration, not a sensible default for a new app.
Choose the scanner that matches the job
| Package | Best use case | Status and platforms | Important trade-off | Recommendation |
|---|---|---|---|---|
mobile_scanner | New cross-platform scanner | Current; Android, iOS, macOS, web | No Linux or Windows camera support; web backends differ | Default choice for most new apps |
flutter_zxing | Broad ZXing format coverage | Current; Android/iOS full, desktop beta | Web unsupported; desktop camera support is limited | Use when its format and native trade-offs fit |
barcode_scan2 | Small Android/iOS scanner surface | Current; Android and iOS | Not cross-platform; native setup still matters | Reasonable for a deliberately mobile-only app |
google_mlkit_barcode_scanning | Direct ML Kit scanning | Current; Android and iOS | Lower-level bridge; no web or desktop solution | Use when native ML Kit control matters |
ai_barcode_scanner | Ready-made scanner UI | Wrapper over mobile_scanner; Android, iOS, macOS, web | Adds an opinionated UI dependency | Use when the UI saves real work |
qr_code_scanner_plus | Existing QRView-style project | Maintenance-only compatibility fork | Not intended to add new features | Keep while planning migration |
qr_code_scanner | Existing legacy QRView project | Maintenance-only; Android and iOS | Underlying frameworks are unmaintained | Migrate rather than choose for new work |
A package that works well on Android and iOS is not automatically a desktop or web answer. Check the target platform before you commit to the API.
mobile_scanner is the default for a new app
mobile_scanner gives you a high-level Flutter widget and controller while using platform-specific scanning implementations underneath. Its package documentation lists CameraX and ML Kit on Android, AVFoundation and Apple Vision on Apple platforms, and different ZXing-based paths on the web. That combination is why it is a better starting point than an older QR-only wrapper for most new projects.
It supports Android, iOS, macOS, and web. It does not support Linux or Windows camera scanning. Web behavior is also not identical to native behavior: browser support and the selected detection backend affect what the user can do. Treat web as a target to verify, not a promise of native parity.
For a basic camera scanner, the current callback gives you a BarcodeCapture. A capture can contain more than one barcode, so handle the collection rather than assuming a single result:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
class ScanView extends StatelessWidget {
const ScanView({super.key});
@override
Widget build(BuildContext context) {
return MobileScanner(
onDetect: (capture) {
for (final barcode in capture.barcodes) {
final value = barcode.rawValue;
if (value != null) {
debugPrint(value);
break;
}
}
},
);
}
}
This example shows the scanner surface. In a real screen, add your own duplicate-result guard before navigating or submitting a form. If the camera does not open, first check the Android camera permission entry, the iOS camera usage description, and the device’s runtime permission for the package’s supported platform. Then check the package’s platform notes before adding a controller, scan window, image input, or web support.
If your Flutter installation itself is the problem, fix that separately with our guide to installing Flutter on Linux. A scanner package cannot compensate for an SDK or native build that is not configured.
When another package makes more sense
flutter_zxing: broad barcode coverage and non-camera desktop decoding
Choose flutter_zxing when the ZXing C++ engine and broad barcode support are more important than a simple cross-platform widget. Android and iOS are the strongest targets. macOS, Linux, and Windows support is beta without camera support, and web is unsupported. That makes it useful for supported native scanning and non-camera decoding workflows, not a general desktop camera solution or a drop-in replacement for every mobile_scanner project.
barcode_scan2: a deliberately small mobile-only choice
barcode_scan2 is reasonable when your app only targets Android and iOS and you want a narrow QR and 2D barcode scanning wrapper. Its smaller scope can be an advantage in an existing mobile codebase. It is not the right answer when web, macOS, Linux, or Windows support is part of the plan.
google_mlkit_barcode_scanning: use the lower-level bridge intentionally
This package bridges Flutter to native Google ML Kit barcode scanning on Android and iOS. It makes sense when your team wants direct access to ML Kit’s model and configuration rather than a ready-made scanner screen. It is not a web or desktop package, and the Flutter plugin is not maintained by Google itself, so account for native version requirements and upgrade work.
ai_barcode_scanner: choose the UI, not a new engine
ai_barcode_scanner wraps mobile_scanner with a ready-to-use interface, overlay customization, and gallery-oriented features. Use it when that prepared UI removes meaningful work. If you need to control the scanning engine or keep the widget surface small, depend on mobile_scanner directly instead.
What to do with qr_code_scanner and qr_code_scanner_plus
The original qr_code_scanner package is marked “Project in Maintenance Mode Only” on pub.dev. Its page also points new projects toward mobile_scanner. Do not treat that as a reason to panic about a working production app; maintenance status is a reason to plan, not automatically a reason to replace code today.
qr_code_scanner_plus is the compatibility path for existing QRView-style applications. Its documentation describes it as a maintenance-only fork and recommends mobile_scanner for new projects. That is a useful distinction: keep the fork when stability and a controlled migration matter, but do not select it for a new feature simply because its API looks familiar.
The migration direction is to replace the old stream-oriented screen with a MobileScanner widget and handle its BarcodeCapture in onDetect. Move navigation or form submission behind a one-result guard, then recheck permissions, lifecycle behavior, and web support. Treat the migration as an API and platform change, not only a dependency rename.
Common implementation problems
When a scanner fails, start with the symptom before replacing the package. Check the package’s current platform instructions before changing application code.
| Symptom | Likely cause | Next check |
|---|---|---|
| The callback fires repeatedly | Camera scanning is continuous | Guard the first accepted value before navigating or submitting |
| Camera never opens | Permission or native configuration is missing | Check the Android camera permission, iOS usage description, and device permission |
| Works on mobile but not web | Browser backend or feature support differs | Read the package’s web backend and browser requirements |
| Scanner breaks after navigation | Controller or camera lifecycle is not handled | Check controller start/pause/resume and dispose it with the owning screen |
| Image scanning is missing | Camera scanning is not the same as file analysis | Confirm the package and target platform expose image analysis before choosing it |
| Build fails after adding the package | Native SDK, minimum OS, or compile requirements do not match | Compare the package’s current Android/iOS requirements with the project |
If you pass a MobileScannerController, check its start(), pause(), and dispose() calls when a route leaves or returns to the scanner. If the requirement is file input, check the package’s current image-analysis API and the target platform before adding a file picker; camera support alone does not provide file analysis.
When the failure is platform-specific, isolate the platform before replacing the package. A permission problem, a camera lifecycle problem, and an unsupported web feature can look identical from the Flutter widget tree. If you need to scan an existing image or file, verify image-analysis support separately; a live-camera widget does not automatically analyze files.
Scanning is not QR generation
Scanner packages read a QR code or barcode through a camera or supported image input. qr_flutter and pretty_qr_code create QR images for your app to display or export. They solve a different problem, so choosing between mobile_scanner and qr_flutter is usually not an either/or decision.
FAQ
What is the best Flutter QR scanner package?
For most new Android, iOS, macOS, and web projects, start with mobile_scanner. Change that choice only when its platform, web, UI, engine, or migration trade-offs do not fit the project.
Is qr_code_scanner still maintained?
Its pub.dev page marks it as maintenance-only. It can still be part of an existing application, but it should not be the default recommendation for a new project.
Does mobile_scanner support web?
Yes, but web detection uses browser-dependent backends and does not have identical behavior to native Android or iOS scanning. Verify the browsers and input features your application needs.
What should replace an old QRView implementation?
Use mobile_scanner for a new direction in most supported targets. Keep qr_code_scanner_plus temporarily when preserving the existing QRView API lowers migration risk, then plan the move rather than treating the fork as a feature-forward package.
Bottom line: choose mobile_scanner unless a clearly stated platform, engine, UI, or migration constraint points elsewhere. The best package is the one whose supported input and target platforms match the application you are actually shipping.







