@bear-block/vision-camera-ocr
A high-performance React Native Vision Camera plugin for real-time OCR (Optical Character Recognition)
Features • Installation • Usage • API Reference • Contributing
Version Compatibility
| Package version | VisionCamera version | Status |
|---|---|---|
| 4.x (this) | v3 / v4 | Stable |
| 5.x | v5 | Coming soon |
Using VisionCamera v5?
VisionCamera v5 introduced a completely new architecture (Nitro Modules) and removed the Frame Processor Plugin system used by this package. This version (4.x) is NOT compatible with VisionCamera v5.
Install the v5-compatible version instead:
yarn add @bear-block/vision-camera-ocr@5See the v5 migration guide for details.
Overview
@bear-block/vision-camera-ocr is a powerful React Native library that provides real-time text recognition capabilities directly within your camera app. Built on top of react-native-vision-camera v3/v4's Frame Processor Plugin system, it leverages native OCR engines for optimal performance:
- Android: Powered by Google ML Kit Text Recognition
- iOS: Powered by Apple's Vision Framework
Perfect for applications requiring real-time text extraction, document scanning, business card readers, or any OCR functionality.
Features
- Real-time Processing — Instant text recognition from camera frames via worklets
- Cross-platform — Native implementation for both Android & iOS
- High Performance — Runs synchronously on the camera thread, zero bridge overhead
- Offline First — No internet connection required, all processing on-device
- Easy Integration — Simple
performOcr(frame)API insideuseFrameProcessor - Configurable — Bounding boxes, confidence scores, recognition level, language hints
- Production Ready — Built with TypeScript and comprehensive error handling
Installation
Prerequisites
| Dependency | Version |
|---|---|
| React Native | 0.79+ |
react-native-vision-camera |
^3.0.0 || ^4.0.0 |
react-native-worklets-core |
^1.5.0 |
Install the package
# Using yarn (recommended)
yarn add @bear-block/vision-camera-ocr
# Using npm
npm install @bear-block/vision-camera-ocr
# Using pnpm
pnpm add @bear-block/vision-camera-ocriOS Setup
cd ios && pod installAndroid Setup
No additional setup required — the package is auto-linked.
Quick Start
Basic Usage
import { Camera, useFrameProcessor } from 'react-native-vision-camera';
import { performOcr } from '@bear-block/vision-camera-ocr';
function MyCameraComponent() {
const device = useCameraDevice('back');
const frameProcessor = useFrameProcessor((frame) => {
'worklet';
const result = performOcr(frame);
if (result?.text) {
console.log('Detected text:', result.text);
}
}, []);
if (device == null) return null;
return (
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
frameProcessor={frameProcessor}
frameProcessorFps={5}
/>
);
}Advanced Usage
import { Camera, useFrameProcessor } from 'react-native-vision-camera';
import { performOcr } from '@bear-block/vision-camera-ocr';
import { runOnJS } from 'react-native-worklets-core';
function AdvancedCameraComponent() {
const device = useCameraDevice('back');
const [detectedText, setDetectedText] = useState('');
const handleText = useCallback((text: string) => {
setDetectedText(text);
}, []);
const frameProcessor = useFrameProcessor((frame) => {
'worklet';
const result = performOcr(frame, {
includeBoxes: true,
includeConfidence: true,
recognitionLevel: 'accurate', // iOS only
});
if (result?.text) {
runOnJS(handleText)(result.text);
}
}, [handleText]);
if (device == null) return null;
return (
<View style={styles.container}>
<Camera
style={StyleSheet.absoluteFill}
device={device}
isActive={true}
frameProcessor={frameProcessor}
frameProcessorFps={3}
/>
{detectedText ? (
<View style={styles.textOverlay}>
<Text style={styles.text}>{detectedText}</Text>
</View>
) : null}
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1 },
textOverlay: {
position: 'absolute',
bottom: 100,
left: 20,
right: 20,
backgroundColor: 'rgba(0,0,0,0.7)',
padding: 15,
borderRadius: 10,
},
text: {
color: 'white',
fontSize: 16,
textAlign: 'center',
},
});API Reference
performOcr(frame, options?)
Performs OCR on a camera frame and returns recognized text. Runs synchronously on the camera thread (worklet-compatible). Returns null when no text is detected.
Parameters
| Parameter | Type | Description |
|---|---|---|
frame |
Frame |
The camera frame from useFrameProcessor |
options |
OcrOptions (optional) |
See below |
OcrOptions
| Option | Type | Default | Platform | Description |
|---|---|---|---|---|
includeBoxes |
boolean |
false |
Both | Include bounding boxes for blocks, lines, and words |
includeConfidence |
boolean |
false |
Both | Include confidence scores |
recognitionLevel |
'fast' | 'accurate' |
'fast' |
iOS | Vision framework recognition level |
recognitionLanguages |
string[] |
— | iOS | Language hints, e.g. ['en-US', 'vi-VN'] |
usesLanguageCorrection |
boolean |
— | iOS | Enable language correction |
Returns
OcrResult | null
type OcrResult = {
text: string; // All recognized text concatenated
blocks?: OcrBlock[]; // Present when includeBoxes is true
};
type OcrBlock = {
text: string;
box?: OcrBox;
lines?: OcrLine[];
};
type OcrLine = {
text: string;
box?: OcrBox;
words?: OcrWord[];
confidence?: number;
};
type OcrWord = {
text: string;
box?: OcrBox;
confidence?: number;
};
type OcrBox = {
x: number; // Normalized 0..1 on iOS, pixel units on Android
y: number;
width: number;
height: number;
};Example
const result = performOcr(frame, {
includeBoxes: true,
includeConfidence: true,
recognitionLevel: 'accurate',
recognitionLanguages: ['en-US', 'vi-VN'],
usesLanguageCorrection: true,
});
if (result) {
console.log('Text:', result.text);
const firstLine = result.blocks?.[0]?.lines?.[0];
if (firstLine?.box) {
console.log('First line box:', firstLine.box);
}
}Platform-Specific Details
Android
- Uses Google ML Kit Text Recognition
- Optimized for Latin script languages
- Automatic language detection
- Bounding boxes returned in pixel units
iOS
- Uses Apple's Vision Framework
- Supports
recognitionLevel,recognitionLanguages,usesLanguageCorrection - Bounding boxes returned normalized (0..1)
Performance Tips
- Use
frameProcessorFps={3-5}for optimal performance - Use
recognitionLevel: 'fast'(default) for real-time,'accurate'for single captures - Debounce text updates via
runOnJSto avoid excessive re-renders - Process frames conditionally (e.g., only when camera is focused)
Troubleshooting
"Failed to load Frame Processor Plugin"
Clean and rebuild:
cd android && ./gradlew clean && cd .. cd ios && pod deintegrate && pod install && cd ..Verify dependencies are installed:
npx react-native configCheck that
react-native-worklets-coreis installed and linked.
Camera Permission
iOS — Add to Info.plist:
<key>NSCameraUsageDescription</key>
<string>This app needs access to your camera to perform OCR</string>Android — Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />No Text Detected
- Ensure good lighting conditions
- Hold camera steady and focus on text
- Try
recognitionLevel: 'accurate'for difficult text - Lower
frameProcessorFpsto give more time per frame
Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
git clone https://github.com/bear-block/vision-camera-ocr.git
cd vision-camera-ocr
yarn install
yarn test
yarn typecheck
yarn lintLicense
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built on top of react-native-vision-camera v3/v4
- Android OCR powered by Google ML Kit
- iOS OCR powered by Apple Vision Framework
Made with by Bear Block
GitHub • Issues • Discussions