Free barcode software libraries are an attractive option for developers. With so many of them available, it can be difficult to pick the best tool for a particular application. In a previous article, we discussed Google’s ML Kit vs. ZXing.
This time, we compare two popular barcode scanner libraries for Flutter: google_mlkit_barcode_scanning and mobile_scanner.
Below is a quick summary before we dive into the details.
💡 Key findings
Supported platforms:
- google_mlkit_barcode_scanning (ML Kit): Android & iOS
- mobile_scanner: Android (ML Kit), iOS (VisionKit), macOS (VisionKit), Web (zxing-js)
Supported barcode types:
- ML Kit: Most common 1D & 2D formats, includes structured data parsing
- mobile_scanner: Same on Android (via ML Kit), more on iOS/macOS/Web (e.g., GS1 DataBar)
Capabilities:
Both libraries can scan multiple codes at once, read from static images, and support omnidirectional scanning.
- ML Kit focuses on barcode detection only, with no built-in camera controls
- mobile_scanner includes camera controls, but support varies by platform
Maintenance and updates:
- ML Kit: Community-maintained Flutter wrapper, dependent on Google releases
- mobile_scanner: Actively developed, frequent releases, with an engaged community
Limitations:
- ML Kit
- Maximum of 10 recognized barcodes per API call
- Unsupported barcode formats (e.g. short ITF codes, ECI QR codes)
- Image resolution requirements, especially problematic for denser barcodes
- mobile_scanner
- Inherits ML Kit’s limits on Android, plus orientation issues
- Barcode detection inconsistencies on Web
- iOS camera focus issues
ML Kit vs. mobile_scanner: A detailed comparison
google_mlkit_barcode_scanning is a Flutter plugin that exposes Google’s native ML Kit Barcode Scanning API, available for Android and iOS. It handles only the barcode detection logic. Developers must manage the camera separately (for example, with the camera
plugin). Below, we’ll usually refer to it simply as ML Kit.
mobile_scanner is a Flutter plugin that bundles camera access and barcode detection in one package. Under the hood, it uses CameraX with ML Kit on Android, AVFoundation with VisionKit on iOS and macOS, and ZXing in the browser. It provides a ready-made Flutter widget.
Supported barcodes
google_mlkit_barcode_scanning (ML Kit) covers a broad set of 1D and 2D barcode formats. Additionally, it will parse structured data such as URLs, ISBNs, and AAMVA driver’s license data.
mobile_scanner inherits its coverage from the underlying library. On Android, this is ML Kit’s, as above. The libraries for iOS/macOS (VisionKit) and Web (ZXing) support more symbologies.
It’s worth noting that on iOS and macOS, UPC-A codes will scan, but it’ll output as an EAN-13. Developers have identified this inconsistency and requested that the barcode format be normalized across platforms.
The table below shows a side-by-side comparison per library and platform.
Barcode types | ML Kit – Android/iOS | mobile_scanner – Android | mobile_scanner – iOS/macOS | mobile_scanner – Web |
UPC-A | ✅ | ✅ | ️️⚠️ | ✅ |
UPC-E | ✅ | ✅ | ✅ | ✅ |
EAN-8 | ✅ | ✅ | ✅ | ✅ |
EAN-13 | ✅ | ✅ | ✅ | ✅ |
ITF (Interleaved 2 of 5) | ✅ | ✅ | ✅ | ✅ |
Code 39 | ✅ | ✅ | ✅ | ✅ |
Code 93 | ✅ | ✅ | ✅ | ✅ |
Code 128 | ✅ | ✅ | ✅ | ✅ |
Codabar | ✅ | ✅ | ✅ | ✅ |
MSI Plessey | ❌ | ❌ | ✅ | ❌ |
GS1 DataBar | ❌ | ❌ | ✅ | ✅ |
GS1 DataBar Expanded | ❌ | ❌ | ✅ | ⌛ |
GS1 DataBar Limited | ❌ | ❌ | ✅ | ❌ |
QR Code | ✅ | ✅ | ✅ | ✅ |
Micro QR Code | ❌ | ❌ | ✅ | ❌ |
Data Matrix | ✅ | ✅ | ✅ | ✅ |
Aztec | ✅ | ✅ | ✅ | ✅ |
PDF417 | ✅ | ✅ | ✅ | ✅ |
Micro PDF417 | ❌ | ❌ | ✅ | ❌ |
MaxiCode | ❌ | ❌ | ❌ | ❌ |
Legend: ✅ Supported ❌ Not supported ⚠️ Decoding issue ⌛ Under development
Capabilities
Both libraries can scan from live camera streams and from still images, handle multiple codes per frame, and work in any orientation. Barcodes are processed fully on-device across for both libraries on all platforms.
ML Kit focuses on recognition only. It does not include camera controls, so torch, focus, or camera switching must be handled separately. On Android, auto-zoom is supported (bundled v17.2.0 and unbundled v18.3.0).
mobile_scanner includes camera controls via CameraX and AVFoundation. Torch and region-of-interest (ROI) functions are not available on Web, and autofocus behavior varies by device.
Feature | ML Kit – Android | ML Kit – iOS | mobile_scanner – Android | mobile_scanner – iOS/macOS | mobile_scanner – Web |
Scan multiple codes at once | ✅ | ✅ | ✅ | ✅ | ✅ |
Scan from images | ✅ | ✅ | ✅ | ✅ | ✅ |
Omnidirectional scanning | ✅ | ✅ | ✅ | ✅ | ✅ |
Camera switching | ❌ | ❌ | ✅ | ✅ | ✅ |
Torch toggle | ❌ | ❌ | ✅ | ✅ | ❌ |
Autofocus | ❌ | ❌ | ⚠️ | ⚠️ | ⚠️ |
Auto-zoom | ✅ | ❌ | ✅ | ❌ | ❌ |
Define ROI | ❌ | ❌ | ✅ | ✅ | ❌ |
Legend: ✅ Supported ❌ Not supported ⚠️ Device dependent
Customizability
The scanner libraries differ in how much they let you tailor both the UI and the scanning logic.
ML Kit for Flutter does not ship with a UI. Developers must handle image frames themselves and then build their own overlays and result screens. This gives you wide latitude in designing your user experience. The detection model at its core, however, is proprietary: You cannot add new barcode formats or tune its behavior beyond some basic parameters.
mobile_scanner, conversely, provides a scanning widget out of the box. You get camera controls, a configurable scan window, and overlay customization options (size and color). You can also set parameters such as detection speed and initial flashlight state.
On Android, iOS, and macOS, it inherits ML Kit’s and Vision Kit’s closed models. The Web library, zxing.js, is more adaptable, but does not ship with features such as torch control or scan-window configuration.
Integration and developer resources
With mobile_scanner, integration is simple. The package manages both the camera pipeline and barcode decoding out of the box, so beyond configuring Android and iOS permissions, little work is needed.
Integrating google_mlkit_barcode_scanning requires a bit more setup. Developers need to set up a camera stream (typically using the camera
plugin) and feed those frames into ML Kit for processing. While this adds complexity, it also provides greater control over how images are captured and processed.
Both libraries are well supported, with clear documentation and community tutorials available. See the table below for the respective resources.
google_mlkit_barcode_scanning | mobile_scanner |
GitHub repository Pub.dev package Documentation | GitHub repository Pub.dev package Documentation Integration tutorial (v6) |
Maintenance and updates
Both libraries are actively maintained and receive regular dependency updates.
The Flutter plugin for ML Kit has solid maintenance health. google_mlkit_barcode_scanning supports Dart 3 and the latest Flutter SDKs. As noted, the core scanning behavior cannot be changed at the plugin level, and deeper fixes and feature additions depend on Google’s roadmap.
mobile_scanner is under active development with frequent releases aimed at cross-platform stability and features. Version 7.0.0 (May 2025) was a notable update. The changes included moving from ML Kit to Apple’s Vision API on iOS and macOS, improving lifecycle handling, and adding options such as autoZoom
, invertImage
, and pausing/resuming scanning.
Ultimately, both depend on their native engines, so future capabilities will have to track upstream changes.
Community and support
google_mlkit_barcode_scanning is community-maintained, unlike the native ML Kit libraries backed by Google. Support is via GitHub and Stack Overflow and is generally timely.
mobile_scanner has a more active community. Issues are raised and addressed quickly, mainly on GitHub, and the pull request history reflects regular activity from both the maintainer and contributors.
Limitations
ML Kit
When using ML Kit in Flutter, it’s important to understand that the google_mlkit_barcode_scanning plugin delegates processing to Google’s native ML Kit API. Its limitations and problems often have their source in the underlying API rather than the wrapper.
Barcode recognition limit
ML Kit can detect up to ten barcodes per image. Even if more are present, the scanner will only return up to ten results per API call.
Unsupported code formats
ML Kit doesn’t support barcodes in the following formats:
- Single-character 1D barcodes: Rare in practice but sometimes used in test environments, samples, or internal labeling.
- ITF codes shorter than six digits: Shorter variants of the standard 14-digit ITF codes that appear in internal tracking labels, product IDs, or temporary tags.
- FNC2–FNC4 encodings: Special control characters sometimes used in barcodes for proprietary systems or to link multiple barcodes in a workflow. ML Kit supports FNC1, but not the less common FNC2–FNC4.
- QR codes in ECI mode: Extended Channel Interpretation (ECI) allows QR codes to use alternative character sets, such as Shift-JIS for Japanese or Arabic scripts. ML Kit does not decode these variants.
GS1 data parsing
Many industries, including retail, healthcare, and logistics, rely on barcodes that use the GS1 system of global standards. ML Kit can decode GS1 barcodes, but returns only the raw string. It does not parse the characteristic Application Identifiers (AIs) such as (01) GTIN, (17) expiration date, or (10) batch. To obtain this structured data, you must implement your own parser.

Raw string | Parsed information |
101234567891124072215240724 | Batch/lot number: 123456789 |
Image resolution requirements
For reliable scans, the smallest bar or module should be at least 2 pixels wide (and tall, for 2D). As a reference, an EAN-13 should be around 190 pixels wide; denser formats like PDF417 need higher resolutions.
Stripping of Code 39 start and stop symbols
The “*
” start/stop markers are removed from the raw value, so results may be returned even if these symbols are missing, potentially causing incorrect scans.
mobile_scanner
mobile_scanner inherits all the limitations of ML Kit on Android. Besides that, users have flagged some more issues:
Web support limitations
On Web, the scanner can initialize and display the camera feed yet fail to detect any barcodes. Some laptop and external cameras lack proper focus, while mobile devices tend to work better. In some cases, the web version does not prompt for camera access, and gallery import is unavailable. Overall, barcode detection on Web is less reliable than on mobile platforms.
Orientation issue on Android
On Android tablets, initializing mobile_scanner can force the screen into portrait even when the app is set to landscape. The preview remains landscape, but the surrounding UI rotates. The issue occurs in both v6 and v7, and common workarounds (e.g., locking orientation in MainActivity or disabling auto-rotate) do not resolve it.
Focus issues on iOS devices
On iPhone Pro models (13 Pro, 14 Pro, 15 Pro), v7 fails to focus at close range, preventing short-distance scans. The v6 code has no such problems, pointing to changes in how v7 handles multi-camera systems on iOS.
While there has not been an official fix, the community has found a workaround: Prioritizing the .builtInTripleCamera
(or similar multi-camera configuration) in the plugin’s iOS code.
Initialization crash on Huawei
On some Huawei Android devices, initialization may throw MobileScannerBarcodeException
/ PlatformException
(“Failed to load deprecated vision dynamite module.”). This is likely caused by runtime loading of a deprecated Google Vision module (Dynamite), which is unavailable on devices without Google Mobile Services.
Which library is the best for you?
mobile_scanner and google_mlkit_barcode_scanning – the most popular Flutter ML Kit plugin – both cover the essentials of barcode scanning. The choice really comes down to what you value most in your project.
If you’re aiming to get scanning up and running quickly, mobile_scanner is the more convenient option. It offers an out-of-the-box camera widget and also covers Web and macOS.
The ML Kit plugin, meanwhile, is better suited for cases where you need consistent decoding behavior across iOS and Android or want deeper control over how images are processed. This makes it a more attractive option for developers building tailored scanning experiences, or those handling images outside a live camera feed.
That said, you will have little influence over bugs or inconsistencies that arise from the underlying native code. For teams that can’t afford such uncertainty – especially in enterprise settings – a commercial SDK with professional support often provides more predictable performance and peace of mind.
Why Krónan switched from ML Kit to Scanbot SDK
Krónan’s experience with a non-commercial scanning library illustrates these points.
ML Kit’s lack of GS1 DataBar support proved a dealbreaker, as this barcode type is essential in grocery retail. Additionally, the team faced persistent problems with accidental scans, where background items would end up in a customer’s digital shopping cart.
Hörður Már Jónsson, Head of Digital Development at Krónan, describes his experience after switching to Scanbot SDK:
“With ML Kit, we couldn’t read DataBar codes at all. We solved this by switching to the Scanbot SDK, which not only added DataBar support, but also fixed a critical issue involving accidental barcode scans. It only took us a few weeks from testing to roll-out, not least thanks to the excellent support from the Scanbot SDK developers.”
By introducing features like a viewfinder and background barcode filtering, the Scanbot SDK gave Krónan a far more reliable and user-friendly solution. Thanks to the flat-fee license model, it also scales smoothly with their growing customer base.
The alternative for enterprise solutions: Scanbot Barcode Scanner SDK
If you’re looking for a reliable and fast barcode scanner, the Scanbot Barcode Scanner SDK is a strong alternative. It supports all common 1D and 2D barcode formats, scans them in as little as 0.04 seconds each, parses a variety of structured data types, and is available for iOS, Android, Web, and all major cross-platform frameworks, including Flutter.
The Scanbot SDK includes ready-to-use UI components, works entirely offline, and comes with enterprise support. The flat pricing keeps costs predictable regardless of usage volume.
Curious to test it for yourself? Try out the demo app or request a free trial license to try our scanner in your app.