NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev · #2792 most downloaded on pub.dev
Barcode and QR code scanner for Flutter on Android, iOS, macOS and the web: a full-screen or embedded scanner UI in one call, built on mobile_scanner.
Last release 24 days ago
14 Sep 2026
Release timing varies
gaps range from 2 weeks to 12 months
Most releases are documented
notes for 21 of 25 stable releases
Nothing withdrawn
no release was ever pulled
4 years old
26 releases · first in 2022
Clearer feedback when a scan is rejected, self-hosting the web decoder without giving up the one-line scanner, and a rewritten README. No API breaks;
Clearer feedback when a scan is rejected, self-hosting the web decoder without giving up the one-line scanner, and a rewritten README. No API breaks; the SDK floor stays at Dart 3.7 / Flutter 3.29.
ScannerLabels.invalidBarcode, noBarcodeFoundInImage and
galleryUnsupported had no effect. They were added in 8.0.0 but never
shown, so translating them changed nothing, and a rejected scan or an empty
image got only a red flash and a haptic. Each now replaces the scan hint for
a couple of seconds, in the same pill and colours, and is announced to screen
readers. invalidBarcode appears when validator rejects a capture from the
camera or a picked image, together with the rejection haptic and throttled by
scanCooldown like it; a scan that reaches onDetect clears it at once.
noBarcodeFoundInImage appears when a picked image yields null or an empty
capture, from the built-in decoder or galleryImageAnalyzer, but not for a
cancelled pick. galleryUnsupported appears when picking or analysing an
image throws UnsupportedError (UnimplementedError included), as a
galleryImagePicker, galleryImageAnalyzer or platform implementation
without still-image support may; the error still reaches
onGalleryScanError (or FlutterError.reportError) as before. Other gallery
errors, such as an unreadable file, show no message. Set a label to '' to
turn that one message off.
The messages follow showScanHint: they appear only where the hint does, so
a scanner with showScanHint: false, and AiBarcodeScanner.embedded, whose
hint is off by default, look exactly as they did. Flashes, haptics,
callbacks and the idle hint are unchanged, and the usual guidance returns
when a message clears.
webBarcodeReader and webBarcodeLibraryScriptUrl on
showAiBarcodeScanner and showAiBarcodeScannerBatch, forwarded to the
scanner as-is. A web app whose Content Security Policy rules out jsDelivr can
now self-host the detection library and keep the one-liner, instead of
pushing AiBarcodeScanner itself.AiBarcodeScannerController.setWebImageDecoderScriptUrl — points the
built-in web image decoder at a self-hosted copy of zxing-wasm without a
scanner on the page, for apps that only scan images they already have with
analyzeScannerImage or analyzeImage. Until now such an app always loaded
zxing-wasm from jsDelivr, because only a mounted AiBarcodeScanner with
webBarcodeLibraryScriptUrl could change that. Like that parameter, the
setting is page-wide and the first URL wins; call it before the first scan,
such as in main. It does nothing outside the web, and does not change where
the camera loads its library from.ScanHint.announce — an optional flag (default false) that marks the
message as a live region, so screen readers read it out when it appears.llms.txt — an integration brief for AI coding assistants, now shipped in
the package: exact signatures and defaults, platform setup, compile-checked
recipes, testing guidance and pitfalls.mobile_scanner; new Flutter 3.47 projects target iOS 15.0 / macOS 12.0), and
documented that a plain AiBarcodeScanner shows a close button only when
ScannerAction.close is enabled.One column per quarter.
…for this migration, it is being treated as a breaking change. The full migration is planned for 9.0.0.
Scanning from the gallery now works on the web, and the scanner works inside
apps built on Flutter 3.47's material_ui. No API breaks, the SDK floor stays
at Dart 3.7 / Flutter 3.29, and two gallery callbacks are deprecated in favour
of more capable ones. See the
migration guide
— moving over is optional until 9.0.0.
mobile_scanner's web backend still throws UnsupportedError from
analyzeImage
(juliansteenbakker/mobile_scanner#1494),
which is why the gallery button used to hide itself in the browser. The
package now brings its own still-image decoder there: the browser decodes the
picked file — any format it can display, with EXIF orientation applied — and
zxing-wasm 3.1.3, the same build mobile_scanner uses for the camera, reads
the pixels. Large photos are read downscaled first, and at full size only if
that finds nothing — never above 16,777,216 pixels, iOS Safari's canvas
limit. The gallery button now appears on the web by default,
and ScannerPlatformSupport.current.analyzeImage is true there. It loads
zxing-wasm from webBarcodeLibraryScriptUrl when an app hosts the library
itself; with a WebBarcodeReader.zxingJs mirror, which it cannot use, the
button stays hidden on the web unless galleryImageAnalyzer is given.ScannerImage — a still image to scan, given as a file path
(ScannerImage.path), encoded bytes (ScannerImage.bytes) or an XFile
(ScannerImage.xFile), with readAsBytes() to read any of them. Bytes work
on every platform: on Android, iOS and macOS, whose decoders only open files,
they are written to a temporary file for the analysis and deleted straight
afterwards.galleryImagePicker on AiBarcodeScanner, AiBarcodeScanner.embedded
and showAiBarcodeScanner. It replaces the built-in image_picker call and
returns a ScannerImage, so a picker that only hands out bytes — a web file
input, the clipboard, a download — can feed the scanner. The picked image
still runs through validator, feedback and the overlay flash.onGalleryImagePick — called with every picked ScannerImage, or
null when the user cancelled, before the image is analysed.galleryImageAnalyzer — replaces the scanner's own decoding of picked
images, on every platform. It receives the image and the formats the scanner
is restricted to, and returns a BarcodeCapture. Use it for a web app whose
Content Security Policy cannot allow jsDelivr, an offline or self-hosted
deployment, or a decoder of your own; the built-in web decoder is then never
loaded.AiBarcodeScannerController.analyzeScannerImage — scans a
ScannerImage your app obtained some other way, such as from a share intent
or the clipboard. It is what the gallery button uses.AiBarcodeScannerController.analyzeImage works on the web. The path
there is a URL the page can fetch: a blob: URL (which is what XFile.path
is in the browser), a data: URL, or an http(s): URL the page is allowed
to read. mobile_scanner is still asked first, so its own implementation
takes over the day it ships one. controller.raw.analyzeImage — the
unwrapped mobile_scanner call — still throws on the web.showAiBarcodeScanner also accepts onGalleryScanError.material_uiFlutter now publishes Material and Cupertino as the separate material_ui and
cupertino_ui packages (usable from Flutter 3.44), while
package:flutter/material.dart still ships in the SDK. A material_ui
MaterialApp provides its own Theme, MaterialLocalizations and
ScaffoldMessenger: types that the
flutter/material widgets this package is built from cannot see. Without
MaterialUiCompatibilityBridge, the scanner threw "No MaterialLocalizations
found" whenever it showed its app bar (as showAiBarcodeScanner does by
default), and BarcodeResultSheet.show threw from showModalBottomSheet
(#198).
material_ui apps without
MaterialUiCompatibilityBridge, in any locale — and in a bare WidgetsApp.
The flutter/material localizations it needs are supplied to its own subtree
only when missing, layered over the app's so the app's locale and text
direction still apply.BarcodeResultSheet.show opens in those apps on a lightweight route of its
own, with the same slide-up entrance, a dimmed barrier that dismisses it, and
drag-down to dismiss. The barrier's screen-reader label is the new
ScannerLabels.dismissSheetLabel.ScaffoldMessenger.
Where there is none to show the "Copied" snack bar, the copy button itself
briefly shows the confirmation and announces it to screen readers; the
confirmation used to be skipped silently.flutter/material Material — which includes a
material_ui Scaffold, even with the bridge installed.Theme — the retry and open buttons, the
disabled batch "Done" button, the disabled copy and share actions — take
their colours from the ScannerTheme when there is no flutter/material
Theme, instead of the SDK's baseline purple and near-black.ScannerTheme.fromColors derives a scanner theme from individual colours
— only primary is required — so a material_ui ColorScheme, which
ScannerTheme.fromColorScheme cannot accept, can still theme the scanner.
Given the same five colours both produce an identical theme;
fromColorScheme now delegates to it.MaterialApp. The result sheet is still
showModalBottomSheet, copying still shows a SnackBar, the controls still
follow the app's ColorScheme, and the scanner inserts no localizations or
Material of its own.flutter/material throughout 8.x. Moving to
material_ui would take theme and localizations away from every app that
has not migrated — there is no reverse bridge — and would raise the Flutter
floor to 3.44, so, as Flutter advises for this migration, it is being treated
as a breaking change. The full migration is planned for 9.0.0.imagePicker → galleryImagePicker. Return
ScannerImage.path(path) for the same behaviour as before. Passing both
trips an assertion.onImagePick → onGalleryImagePick. It is still called, after
onGalleryImagePick, for a cancelled pick and for any image with a path, but
not for an image picked as bytes, which has none.AiBarcodeScanner or AiBarcodeScanner.embedded now
produces a deprecated_member_use info in the analyzer, which
flutter analyze --fatal-infos treats as a failure.cdn.jsdelivr.net, then its WebAssembly
binary from fastly.jsdelivr.net — roughly 460 KB compressed, 1.1 MB
uncompressed, and cached by the browser afterwards. Nothing is downloaded
until an image is scanned, and nothing at all when mobile_scanner has
already loaded zxing-wasm for the camera.https://cdn.jsdelivr.net and
'wasm-unsafe-eval' in script-src, and https://fastly.jsdelivr.net in
connect-src — plus blob:, through which a picked file is read back, and
data: if you pass data: URLs to analyzeImage or ScannerImage.path.
When the decoder cannot load, or the image cannot be read, the scan fails
with a MobileScannerBarcodeException that says what to allow. A failed
download is not remembered — not even one that failed under the camera's
zxing-wasm reader — so the next scan tries again. Apps that cannot allow
these hosts, or that work offline, can pass galleryImageAnalyzer.analyzeScannerImage from your own UI.AiBarcodeScannerController.analyzeImage and analyzeScannerImage now run
one analysis at a time per controller on Android, iOS and macOS. On Android,
mobile_scanner tracks only one: a call that overlapped another used to
leave the earlier one waiting forever.material_ui app, the few strings the scanner does not render itself —
the text selection toolbar and some framework tooltips — use the SDK's English
defaults. Everything in ScannerLabels is unaffected.mobile_scanner 7.4.1 needs
Android Gradle Plugin 8.9.1+, compileSdk 36, minSdk 23 and Kotlin Gradle
Plugin 2.x, which apps created from Flutter 3.29-era templates have to raise.
Nothing changed in 8.1.0 itself.web: ^1.0.0 is now a direct dependency, for the web decoder. It was already
required by mobile_scanner with the same constraint, so resolution does not
change.Raised the floor to mobile_scanner >= 7.4.1 , published a few hours after 8.0.0's dependency audit. It fixes the false-positive plugins that apply Kot
mobile_scanner >= 7.4.1, published a few hours afterplugins that apply Kotlin Gradle Plugin (KGP): mobile_scanner warning onEXC_BAD_ACCESS on iOS when the app is terminated with the camera running.>=7.4.0 constraint already resolved 7.4.1 for a fresh pub get;flutter clean.cannot find symbol: class MobileScannerPlugin. Verified: the build failsA rewrite. Every camera capability of mobile_scanner 7.4.0 is now a plain widget parameter, on top of a scanner UI that is responsive, capability-awar
A rewrite. Every camera capability of mobile_scanner 7.4.0 is now a plain
widget parameter, on top of a scanner UI that is responsive, capability-aware,
themeable and localisable. See the
migration guide
— most apps need a one-line change or none at all.
GalleryButtonType.none hid every control, not just the gallery buttonappBarBuilder or a child no longer removes the controls either.Null check operator used on a null value when the scanner was poppedsetState after an await; it listens to therestrictDetectionToScanWindow: false).CupertinoIcons, whose font is only bundled when the appcupertino_icons. Defaults are now Material icons, whichuses-material-design: true already ships.mobile_scanner >= 7.4.0, which pulls ML Kit 17.3.0 — 16 KB aligned on bothuseAppLifecycleState wasMobileScanner only manages the lifecycle for a controller itpreferredOrientations.onGalleryScanError.onOpenSettings hook.ScannerCornerPainter and ScanningLinePainter under-reported repaints,cornerLength, lineThickness or the colours did nothing.ScannerOverlayConfig.animation was accepted and ignored. It is honouredkey was forwarded to the inner MobileScanner, soAiBarcodeScanner(key: GlobalKey()) threw "Multiple widgets used the samedidUpdateWidget leaked or was wronglygalleryIcon was ignored by the icon-style gallery button.ValueNotifier and its timer are disposed; every write ismounted.A multi-agent adversarial review of the rewrite, before release, turned up a
further set of defects; all are fixed and pinned by tests.
ScanWindowConfig.resolve passed an unclamped minWidth as thenum.clamp whose upper limit was the available width.clamp throws ArgumentError — not a debug-only assert — when the lowercontroller left the preview driving the disposed one.MobileScanner captures its controller in a late final field, so it neverScanWindowShape.fullPreview.SingleTickerProviderStateMixin does not release its claim when a ticker ismaxScans when one capture carried more barcodesonScanComplete could fire more than onceScanValidators.matches rejected values its pattern did match.matchAsPrefix takes the first alternative that fits and never backtracks,RegExp('a|ab') rejected ab. The pattern is now properly anchored, andscanCooldown.mailto: and sms: URIs were form-encoded, so a space reached the mail+.actionUri returned an unopenable relative URI for a URL payload withScanWindowConfig.copyWith could not clear a builder, so a builder-basedclearBuilder.showBarcodeHighlights works there. Also corrected doc comments onAiBarcodeScanner.embedded, appBarBuilder and analyzeImage.AiBarcodeScannerController — a facade over the camera and the scanstart/stop/pause, pauseScanning/resumeScanning,toggleTorch/setTorch, switchCamera/switchLens/useCloseRangeLens,setZoomScale/resetZoomScale, setFocusPoint, analyzeImage, batchcollect/clearCollected, plus state and the barcodes stream..raw reaches the underlying MobileScannerController.mobile_scanner parity as widget parameters: formats,detectionSpeed, detectionTimeoutMs, facing, lensType,cameraResolution, torchEnabled, autoStart, autoZoom, invertImage,initialZoom, returnImage, webBarcodeReader,webBarcodeLibraryScriptUrl.showAiBarcodeScanner and showAiBarcodeScannerBatch — open a scannerAiBarcodeScanner.embedded — the scanner without a Scaffold, forsingle, continuous (with scanCooldown) and batchmaxScans and onScanComplete).ScannerTheme — a palette for the scanner chrome, withScannerTheme.fromColorScheme for brand matching. Overlay colours are nowScannerLabels — every user-visible string, overridable, with Englishintl dependency.ScanWindowConfig — declarative scan window sizing: auto, square,wide, tall, fullPreview or a builder, with min/max bounds that keep theScannerFeedbackConfig — configurable haptics and sound, aScannerFeedbackConfig.silent preset, and an onFeedback hook for your ownScanValidators — formats, types, contains, startsWith,matches, url, length, combined with all / either.BarcodeFormatSets — curated presets: qrOnly, twoDimensional,retail, logistics, documents.ScannerPlatformSupport — the per-platform capability matrix. ControlsbestValue, typeLabel, typeIcon,actionUri, boundingBox, fields (structured Wi-Fi, contact, calendar,BarcodeFormat.displayName.BarcodeResultSheet — a ready-made sheet that renders the structuredScannerAction.zoom, .lens and .close.showBarcodeHighlights).idleHintDelay when nothing hasonScannerStarted, onError, onOpenSettings, onZoomChanged,onTorchChanged, onClose, onGalleryScanError callbacks.controller takes an AiBarcodeScannerController. UseAiBarcodeScannerController.fromMobileScanner(existing) to wrap one yougalleryButtonText → labels: ScannerLabels(galleryButton: …).setPortraitOrientation → preferredOrientations.onCustomImagePicker → imagePicker, which only chooses thechild is drawn in addition to the controls, not instead ofoverlayBuilder receives the resolved scanWindow.ScannerOverlayConfig.backgroundBlurColor →backgroundColor; colour fields are nullable.detectionSpeed is noDuplicates, which suits aErrorBuilder → ScannerErrorView.universal_platform dependency is replaced by kIsWeb anddefaultTargetPlatform.mobile_scanner >=7.4.0 <8.0.0; image_picker >=1.1.2 <2.0.0 (a loose--fatal-infos, checks formatting with dart formatflutter format no longer exists), runs the tests, scores with pana, andAdded child parameter to AiBarcodeScanner
Added comprehensive documentation for supported barcode formats including PDF417
Improvements:
restoreOrientationsOnClose parameterDocumentation:
BREAKING CHANGES BY [MOBILE_SCANNER](https://pub.dev/packages/mobile_scanner):
BREAKING CHANGES BY MOBILE_SCANNER:
- [iOS] iOS 15.5.0 is now the minimum supported iOS version.
- [iOS] Updates MLKit to version 7.0.0.
- [iOS] Updates the minimum supported XCode version to 15.3.0.
Improvements:
- [MacOS] Added the corners and size information to barcode results.
- [MacOS] Added support for `analyzeImage`.
- [MacOS] Added a Privacy Manifest.
- [web] Added the size information to barcode results.
- [web] Added the video output size information to barcode capture.
- Added support for barcode formats to image analysis.
- Updated the scanner to report any scanning errors that were encountered during processing.
- Introduced a new getter `hasCameraPermission` for the `MobileScannerState`.
- Fixed a bug in the lifecycle handling sample. Now instead of checking `isInitialized`,
the sample recommends using `hasCameraPermission`, which also guards against camera permission errors.
- Updated the behavior of `returnImage` to only determine if the camera output bytes should be sent.
- Updated the behavior of `BarcodeCapture.size` to always be provided when available, regardless of `returnImage`.
- [iOS] Excluded the `armv7` architecture, which is unsupported by MLKit 7.0.0.
- Added a new `onDetectError` error handler to the `MobileScanner` widget, for use with `onDetect`.
Bugs fixed:
- Fixed a bug that would cause the scanner to emit an error when it was already started. Now it ignores any calls to start while it is starting.
- [MacOS] Fixed a bug that prevented the `anaylzeImage()` sample from working properly.
- Fixed a bug that would cause onDetect to not handle errors.
setPortraitOrientation bool added. Now you can set the orientation.
- dependency updates
- dependency updates
BREAKING CHANGES: - mobile_scanner: ^5.1.1
BREAKING CHANGES:
gallery button hide option added
Nothing published for this version
Nothing published for this version
Nothing published for this version
Jump to 3.4.1 to match the version of mobile_scanner
Nothing published for this version
validateText and validateType deprecated removed
- Readme updated
Added validator property, Deprecated validateText and validateType by @MahmoudKhalid
- mobile_scanner: ^3.0.0 added - #25 fixed - #32 added, Thanks to @Abhinav-Satija
Nothing published for this version
- Dependency updates - mobile_scanner: ^3.0.0-beta.1
- multi scan bug fixed
Added a button to turn the LED on and off.
- Documentation updated
Your coding agent can read these notes before it upgrades. Set up the MCP server →