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 barKoder's AR Capabilities 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 Future of Barcode Scanning in 2026: AI, Mobile Vision, and Real-Time Data Intelligence

barKoder provides advanced mobile and web barcode scanning solutions designed for modern applications. With powerful SDKs for multiple platforms, barKoder enables developers to integrate fast, accurate, and reliable barcode scanning directly into their apps. Built to leverage native device capabilities, the technology delivers high performance even in challenging environments such as low light, damaged barcodes, or high-speed scanning scenarios.

Apr 14, 2026

Info

recentArticle

Barcode and OCR SDK Comparison: barKoder vs Scanbot vs Scandit vs Dynamsoft

Barcode scanning and Optical Character Recognition (OCR) technologies are essential for modern mobile and enterprise applications. Solutions from companies like barKoder, Scanbot, Scandit, and Dynamsoft enable developers to capture data quickly from barcodes, documents, and ID cards. These SDKs help businesses digitize workflows, improve accuracy, and automate processes across industries such as logistics, retail, healthcare, and fintech.

Apr 10, 2026

Info