Building flutter_native_ocr: A Native OCR Flutter Plugin from Idea to Production

June 14, 2025

As a mobile developer, I often work with apps that need to extract text from images. Whether it's scanning documents, reading text from photos, or processing business cards, OCR (Optical Character Recognition) is something I deal with regularly.

I've been working on a project for the last 6 months where OCR was a main feature of the app. While looking for Flutter OCR solutions, I found that existing solutions had some limitations. Some used native Android with ML Kit but didn't have proper iOS support with same accuracy - they were using the same ML Kit on iOS with limitations. Others had native iOS implementation but lacked proper native Android support and production-grade performance.

Since OCR was such a critical part of my project, I decided to create my own plugin - flutter_native_ocr - that would provide true native implementation on both platforms.

The Problem

While working on my project, I found that existing OCR plugins for Flutter had some issues:

  1. Inconsistent Platform Support: Most plugins either had good native support on one platform but used suboptimal solutions on the other
  2. Inconsistent Performance: The mixed approaches led to different experiences on each platform
  3. Setup Complexity: Some required extensive configuration
  4. Maintainability Issues: Mixing direct native code integration with plugin approaches across platforms would be difficult to maintain long-term

Since my app heavily relied on OCR functionality, I needed something more reliable and consistent across both platforms.

My Solution: True Native OCR

Initially, I tried integrating native iOS code directly into my Flutter project using the Vision framework, and it worked quite well. However, I realized that maintaining part of the OCR functionality as native code on iOS while using a plugin approach on Android would be much more difficult to maintain in the future. Having different implementation approaches across platforms would make the codebase harder to manage and update.

This led me to decide on creating a proper plugin that would provide native support for both platforms - iOS with Vision framework and Android with ML Kit.

I decided to build a plugin that would:

  • Use the best native OCR framework on each platform (Apple Vision on iOS, Google ML Kit on Android)
  • Work completely offline with on-device processing
  • Provide a simple API that developers can easily use
  • Ensure privacy by keeping all data on the device
  • Deliver fast and accurate results on both platforms

Technical Architecture

The plugin leverages platform-specific OCR frameworks:

iOS Implementation:

  • Uses Apple's Vision framework, which is highly accurate and optimized for iOS devices
  • Supports iOS 13.0 and later
  • Processes images entirely on-device

Android Implementation:

  • Uses Google ML Kit Text Recognition v2 (v16.0.1)
  • Requires Android API level 21 or later
  • Also provides on-device processing

Key Features

1. High Accuracy Text Recognition

Both Apple Vision and Google ML Kit are industry-leading OCR technologies that provide excellent accuracy for text recognition in various conditions.

2. Multiple Language Support

The plugin automatically detects and recognizes text in multiple languages without requiring additional configuration.

3. Wide Format Support

Supports all major image formats:

  • iOS: JPEG, PNG, HEIF/HEIC, TIFF, BMP, GIF
  • Android: JPEG, PNG, BMP, GIF, WebP

4. Privacy-First Design

All image processing happens on the device. No data is sent anywhere, ensuring complete user privacy.

5. Simple API

The plugin provides a clean, straightforward API:

final ocr = FlutterNativeOcr();
String text = await ocr.recognizeText('/path/to/image.jpg');

Why Native Implementation Matters

Using native frameworks provides several benefits:

  • No Internet Required: Everything works offline
  • Fast Processing: Native frameworks are optimized for each platform
  • High Accuracy: Apple Vision and Google ML Kit are industry-leading technologies
  • Privacy: No data leaves the device
  • Reliable: No dependency on external services

Testing and Optimization

I spent considerable time testing the plugin with:

  • Various image qualities and resolutions
  • Different lighting conditions
  • Multiple languages and text orientations
  • Different device configurations

How I'm Using It

Currently, I'm using this plugin in a production app for document scanning. The app processes various types of documents, and the OCR accuracy has been excellent on both iOS and Android devices. Users can scan documents offline, and the text extraction happens instantly on their device.

Code Example

Here's a simple example of how developers can use the plugin:

import 'package:flutter_native_ocr/flutter_native_ocr.dart';
import 'package:image_picker/image_picker.dart';

class OCRScreen extends StatefulWidget {
  @override
  _OCRScreenState createState() => _OCRScreenState();
}

class _OCRScreenState extends State<OCRScreen> {
  final _ocr = FlutterNativeOcr();
  String _recognizedText = '';

  Future<void> _pickAndScanImage() async {
    final picker = ImagePicker();
    final image = await picker.pickImage(source: ImageSource.camera);

    if (image != null) {
      try {
        final text = await _ocr.recognizeText(image.path);
        setState(() {
          _recognizedText = text;
        });
      } catch (e) {
        print('OCR Error: $e');
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('OCR Scanner')),
      body: Column(
        children: [
          ElevatedButton(
            onPressed: _pickAndScanImage,
            child: Text('Scan Image'),
          ),
          if (_recognizedText.isNotEmpty)
            Expanded(
              child: Padding(
                padding: EdgeInsets.all(16),
                child: Text(_recognizedText),
              ),
            ),
        ],
      ),
    );
  }
}

Publishing and Distribution

The plugin is available on pub.dev as flutter_native_ocr and can be easily added to any Flutter project:

dependencies:
  flutter_native_ocr: ^0.1.0

Lessons Learned

Technical Insights

  1. Platform-Specific Optimization: Native implementations always outperform cross-platform alternatives for performance-critical features
  2. Error Handling: Proper error handling across platform boundaries is crucial
  3. Documentation: Clear documentation and examples are essential for plugin adoption

Development Process

  1. Testing Early: Testing on real devices from the beginning saved time later
  2. Community Feedback: Early feedback from developers helped improve the API design
  3. Incremental Development: Building features incrementally made the development process manageable

Future Enhancements

I'm planning several improvements for future versions:

  1. Advanced OCR Options: Language hints, confidence scores, and region detection
  2. Batch Processing: Processing multiple images in a single call
  3. Custom Models: Support for specialized text recognition models
  4. Real-time OCR: Live text recognition from camera feed

Conclusion

Creating this plugin solved a real problem I was facing in my project. Sometimes the best solution is to use the native tools provided by each platform rather than trying to find a one-size-fits-all approach.

The plugin is now available for other developers who might face similar challenges. It's been downloaded by 100+ developers in just the first week, which shows there was definitely a need for this kind of solution.

For anyone working on Flutter apps that need OCR functionality, this plugin offers a simple, privacy-focused, and reliable solution that works entirely on-device.


Resources:

Thanks for reading! If you have any questions about the plugin or suggestions for improvements, feel free to reach out or contribute to the project.