Blog cover for a barKoder Flutter SDK tutorial.

Ready Barcode Scanner App with barKoder Flutter SDK

This tutorial demonstrates how to build a complete, production-ready barcode scanning application using the barKoder Flutter SDK. The barKoder SDK is a powerful, enterprise-grade barcode scanning solution that leverages native device capabilities to deliver exceptional performance and accuracy.

Why Barkoder SDK?

The barKoder SDK stands out because:

  • 40+ barcode symbologies (1D and 2D) – From traditional UPC/EAN codes to modern 2D matrix codes, the SDK handles virtually any barcode format you'll encounter in commercial, industrial, or consumer applications.
  • Multiple scanning modes optimized for different use cases – Rather than a one-size-fits-all approach, barKoder provides specialized modes like Continuous Scanning, VIN Scanning, and Document Mode that are pre-configured for specific industries.
  • Advanced Enterprise Features – Leverage high-end capabilities such as Direct Part Marking (DPM) for industrial applications and MatrixScan AR for interactive, augmented reality overlays.
  • High performance with hardware-accelerated decoding - The SDK utilizes native device capabilities and optimized algorithms to achieve real-time scanning even on mid-range devices.
  • Flexible configuration for any scanning scenario – Every aspect of the scanner behavior can be customized, from decoding speed to resolution and ROI.

What You'll Build

By the end of this tutorial, you'll have built a feature-rich scanning app with:

  • Real-time barcode scanning – Instant barcode detection and decoding with configurable feedback.
  • Gallery image scanning – Scan barcodes from existing photos in your device's gallery.
  • Configurable settings – Full control over scanner behavior, performance, and user experience.
  • Scan history tracking – Persistent storage of scan results with timestamps and images.
  • Multiple specialized scanning modes – Switch between different modes optimized for various use cases.
  • Export functionality – Share scan results via CSV or other formats.
  • Camera controls – Flash, zoom, and camera switching capabilities.
Side-by-side demonstration of the barKoder Flutter SDK app. The left screen shows a real-time QR code detection on a package, and the right screen shows the 'Scan from Photo' feature successfully decoding a 1D barcode from a gallery image.
Side-by-side demonstration of the barKoder Flutter SDK app.

Project Setup

Install dependencies

            flutter pub get

        

Make sure pubspec.yaml includes barKoder:

            dependencies:
  barkoder_flutter: ^1.6.7
  flutter_dotenv: ^5.2.1

        

Add your license key

Create .env in the project root:

            BARKODER_LICENSE_KEY=YOUR_LICENSE_KEY

        

Load it in main.dart:

            Future<void> main() async {
  await dotenv.load(fileName: ".env");
  runApp(const MyApp());
}

        

Platform permissions

  • Android: camera permission in android/app/src/main/AndroidManifest.xml
  • iOS: NSCameraUsageDescription in ios/Runner/Info.plist

Run the app

            flutter run

        

Core Scanner Integration

The scanner view is created with BarKoderView and a callback that gives you the barKoder controller:

            BarKoderView(
  licenseKey: dotenv.env['BARKODER_LICENSE_KEY'] ?? '',
  onBarkoderViewCreated: _onBarkoderViewCreated,
)

        
            void _onBarkoderViewCreated(Barkoder barkoder) async {
  _barkoder = barkoder;
  await _loadSavedSettings();
  _configureBarkoderView();
}

        

After setup, scanning starts with:

            void _startScanning() {
  _barkoder?.startScanning((result) => _handleScanResult(result));
}

        

App Architecture (Quick Overview)

Key files in this project:

  • lib/screens/scanner_screen.dart: live scanning UI and runtime behavior
  • lib/services/barcode_config_service.dart: mode presets and barKoder tuning
  • lib/services/history_service.dart: persistent scan history
  • lib/constants/modes.dart: mode IDs used across the app

This split keeps scanner logic clean: UI is in the screen, while mode-specific barKoder config is centralized in a service.

Handling Scan Results

In this app, every successful decode:

  • Reads decoderResults
  • Pauses scanning in single-scan modes
  • Saves scan metadata
  • Stores images/thumbnails when available
  • Writes to persistent history
            void _handleScanResult(BarkoderResult result) {
  if (result.decoderResults.isEmpty) return;

  final decoderResult = result.decoderResults.first;
  final item = HistoryItem(
    text: decoderResult.textualData,
    type: decoderResult.barcodeTypeName,
    image: null,
    timestamp: DateTime.now().millisecondsSinceEpoch,
    count: result.decoderResults.length,
  );

  setState(() => _scannedItems.insert(0, item));
  HistoryService.addScan(text: item.text, type: item.type, image: item.image);
}

        

In single-scan modes the app pauses the session, shows a result card, and then resumes only when the user continues. In continuous-like modes, scanning stays active and deduplication is controlled through threshold settings.

Scanning Modes

Modes are defined in lib/constants/modes.dart and configured in lib/services/barcode_config_service.dart.

  • 1d / 2d: targeted symbology groups
  • continuous: repeated scanning without closing session
  • multiscan: multiple results + caching behavior
  • vin: VIN restrictions + focused ROI + slower/high-quality decode
  • dpm: DataMatrix DPM mode tuned for direct-part-marked codes
  • deblur: UPC/EAN deblur for hard labels
  • dotcode: dedicated dotcode mode + narrow ROI
  • ar_mode: interactive AR overlays
  • mrz: ID document scanning mode

Example (VIN and DPM tuning):

            case ScannerModes.vin:
  barkoder.setEnableVINRestrictions(true);
  barkoder.setRegionOfInterest(0, 35, 100, 30);
  barkoder.setDecodingSpeed(DecodingSpeed.slow);
  barkoder.setBarkoderResolution(BarkoderResolution.FHD);
  break;

case ScannerModes.dpm:
  barkoder.setDatamatrixDpmModeEnabled(true);
  barkoder.setRegionOfInterest(40, 40, 20, 10);
  barkoder.setDecodingSpeed(DecodingSpeed.slow);
  barkoder.setBarkoderResolution(BarkoderResolution.UHD);
  break;

        

For AR mode, the project enables:

  • setARMode
  • setARLocationType
  • setARHeaderShowMode
  • setAROverlayRefresh
  • setARDoubleTapToFreezeEnabled

For continuous and multiscan flows, it also configures duplicate suppression and maximum result behavior.

Gallery Image Scanning

This project also scans static images from the user gallery.

Flow:

  1. Pick image with image_picker
  2. Convert to base64
  3. Use Barkoder scanImage for decode
            void _onBarkoderViewCreated(Barkoder barkoder) {
  _barkoder = barkoder;
  _configureBarkoderForGallery(barkoder);
  barkoder.scanImage(_handleResult, widget.base64Image);
}

        

The gallery scanner runs inside a hidden BarkoderView with a timeout fallback, so the user is not stuck waiting indefinitely on problematic images.

Runtime Scanner Controls

The scanner screen supports live controls commonly needed in production apps:

  • Flash toggle (setFlashEnabled)
  • Zoom toggle (setZoomFactor)
  • Front/back camera switch (setCamera)
  • Runtime settings updates (_applySettingChange)

Settings are persisted per-mode in SharedPreferences (scanner_settings_<mode>), so users keep their preferred behavior across app restarts.

Performance Tuning Tips

The current implementation already includes practical defaults:

  • ROI for faster detection (setRegionOfInterest)
  • Duplicate suppression in continuous flows (setThresholdBetweenDuplicatesScans)
  • Mode-based decoding speed (normal, slow)
  • Mode-based resolution (HD, FHD, UHD)
  • Optional image/location payload control for throughput-sensitive cases

If you optimize for raw speed, reduce output payloads and tighten ROI first.

  • General retail/logistics: DecodingSpeed.normal + BarkoderResolution.HD
  • Small or difficult labels: DecodingSpeed.slow + tighter ROI
  • Image-based scanning: DecodingSpeed.rigorous
  • Industrial DPM: DPM mode + stricter ROI + slower decoding

Common Pitfalls

  • Missing/invalid BARKODER_LICENSE_KEY in .env
  • Enabling too many heavy result payloads in high-throughput modes
  • Using broad ROI in workflows that only need center scanning
  • Not separating mode presets from UI logic (harder to maintain at scale)

Conclusion

This Flutter app shows a full barKoder integration pattern:

  • Flexible mode-based scanner configuration
  • Real-time and gallery scanning
  • Persisted settings/history
  • User controls for flash, zoom, camera, and output behavior

For teams building scanner-heavy workflows in logistics, retail, manufacturing, or identity flows, this architecture is a solid baseline you can extend quickly.

Resources

Latest Barcode Scanner SDK Articles,
Tutorials, and News

recentArticle

The Ultimate Guide to Choosing and Integrating a Barcode API for Modern Applications

Unlock the power of modern data capture with our comprehensive guide to selecting and integrating a barcode API. Learn how software-based SDKs are replacing traditional hardware, explore advanced features like MatrixSight® for damaged codes, and discover how to implement high-performance scanning across iOS, Android, and Web platforms.

Mar 27, 2026