react-native-cogni-vision-rnroboflow
v0.4.0
Published
roboflow wrapper for react native
Maintainers
Readme
react-native-cogni-vision-rnroboflow
⚡️ React Native SDK for Roboflow - Run computer vision models on iOS devices with Turbo Modules
Run object detection models locally on your iOS device using models trained on Roboflow. Built with React Native's new Turbo Module architecture for optimal performance.
✨ Features
- 🎯 Object Detection - Detect objects in images with high accuracy
- ⚡️ Turbo Module Architecture - Built on React Native's new architecture for better performance
- 📱 Local Inference - Run models on-device, no API calls needed after model download
- 🔒 Privacy First - Your images never leave the device
- 🎚️ Configurable - Adjust confidence thresholds, overlap, and max detections
- 📦 TypeScript Support - Full type definitions included
- 🔄 Backward Compatible - Works with both old and new React Native architectures
📋 Requirements
- React Native >= 0.68
- iOS >= 15.4
- Xcode >= 14
- Min Deployment Target >= 18.6
- A Roboflow account and API key (Sign up free)
🚀 Installation
npm install react-native-cogni-vision-rnroboflow
# or
yarn add react-native-cogni-vision-rnroboflowiOS Setup
cd ios && pod install && cd ..Enable New Architecture (Optional - Recommended)
For full Turbo Module benefits, enable the New Architecture in ios/Podfile:
ENV['RCT_NEW_ARCH_ENABLED'] = '1'Then reinstall pods and rebuild:
cd ios && pod install && cd ..
npx react-native run-iosNote: The package works with both old and new architectures automatically!
📖 Usage
Basic Example
import Roboflow from 'react-native-cogni-vision-rnroboflow';
async function runDetection() {
// 1. Initialize with your API key
await Roboflow.initialize('YOUR_ROBOFLOW_API_KEY');
// 2. Load your model
await Roboflow.loadModel('your-model-id', 1);
// 3. Run detection on an image
const result = await Roboflow.detectObjects('file:///path/to/image.jpg');
console.log(`Found ${result.predictions.length} objects`);
result.predictions.forEach(pred => {
console.log(`${pred.class}: ${(pred.confidence * 100).toFixed(1)}%`);
});
}Complete Example with Image Picker
import React, { useEffect, useState } from 'react';
import { View, Button, Image, Text, StyleSheet, ScrollView } from 'react-native';
import Roboflow from 'react-native-cogni-vision-rnroboflow';
import { launchImageLibrary } from 'react-native-image-picker';
function App() {
const [ready, setReady] = useState(false);
const [imageUri, setImageUri] = useState(null);
const [predictions, setPredictions] = useState([]);
useEffect(() => {
async function setup() {
try {
await Roboflow.initialize('YOUR_API_KEY');
await Roboflow.loadModel('your-model-id', 1);
setReady(true);
console.log('✅ Roboflow ready!');
} catch (error) {
console.error('Setup failed:', error);
}
}
setup();
}, []);
const pickAndDetect = async () => {
const result = await launchImageLibrary({ mediaType: 'photo' });
if (result.assets?.[0]?.uri) {
setImageUri(result.assets[0].uri);
const detections = await Roboflow.detectObjects(result.assets[0].uri);
setPredictions(detections.predictions);
console.log(`Inference time: ${detections.inferenceTime}ms`);
}
};
return (
<ScrollView style={styles.container}>
<Text style={styles.title}>Roboflow Object Detection</Text>
<Button
title="Pick Image & Detect"
onPress={pickAndDetect}
disabled={!ready}
/>
{imageUri && (
<Image source={{ uri: imageUri }} style={styles.image} />
)}
{predictions.length > 0 && (
<View style={styles.results}>
<Text style={styles.resultsTitle}>
Detections ({predictions.length})
</Text>
{predictions.map((pred, index) => (
<View key={index} style={styles.prediction}>
<Text style={styles.predClass}>{pred.class}</Text>
<Text style={styles.predConf}>
{(pred.confidence * 100).toFixed(1)}%
</Text>
</View>
))}
</View>
)}
</ScrollView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
image: {
width: '100%',
height: 300,
resizeMode: 'contain',
marginVertical: 20,
},
results: {
marginTop: 20,
},
resultsTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 10,
},
prediction: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10,
backgroundColor: '#f0f0f0',
marginBottom: 5,
borderRadius: 5,
},
predClass: {
fontSize: 16,
fontWeight: '600',
},
predConf: {
fontSize: 16,
color: '#666',
},
});
export default App;📚 API Reference
initialize(apiKey: string): Promise<void>
Initialize Roboflow with your API key. Must be called before any other methods.
Parameters:
apiKey(string) - Your Roboflow API key from roboflow.com
Example:
await Roboflow.initialize('your_api_key_here');Throws:
- Error if API key is invalid or initialization fails
loadModel(modelId: string, version: number): Promise<ModelInfo>
Load a model from Roboflow. The model is downloaded and cached locally for offline use.
Parameters:
modelId(string) - Your model ID from Roboflow (e.g., 'my-detector')version(number) - The model version number (e.g., 1, 2, 3)
Returns:
{
success: boolean;
modelName?: string;
modelType?: string;
}Example:
const info = await Roboflow.loadModel('playing-cards', 1);
console.log(`Loaded: ${info.modelName}`);Throws:
- Error if Roboflow is not initialized
- Error if model doesn't exist or version is invalid
detectObjects(imageUri: string): Promise<DetectionResult>
Run object detection on an image.
Parameters:
imageUri(string) - Image URI (supportsfile://,data:image/...,http://,https://)options(optional object):confidence(number, 0-1, default: 0.5) - Minimum confidence thresholdoverlap(number, 0-1, default: 0.5) - IoU threshold for non-max suppressionmaxDetections(number, default: 100) - Maximum detections to return
Returns:
{
predictions: Array<{
class: string; // Object class name
confidence: number; // Confidence score (0-1)
x: number; // Center X coordinate
y: number; // Center Y coordinate
width: number; // Bounding box width
height: number; // Bounding box height
}>;
inferenceTime: number; // Time taken in milliseconds
}Example:
const result = await Roboflow.detectObjects('file:///path/to/image.jpg');
result.predictions.forEach(pred => {
console.log(`${pred.class} at (${pred.x}, ${pred.y})`);
});Throws:
- Error if no model is loaded
- Error if image URI is invalid
- Error if detection fails
unloadModel(): Promise<void>
Unload the current model to free up memory.
Example:
await Roboflow.unloadModel();isInitialized(): boolean
Check if Roboflow has been initialized.
Returns: true if initialized, false otherwise
Example:
if (Roboflow.isInitialized()) {
console.log('Ready to load models');
}isModelLoaded(): boolean
Check if a model is currently loaded.
Returns: true if a model is loaded, false otherwise
Example:
if (Roboflow.isModelLoaded()) {
console.log('Ready to detect objects');
}🖼️ Image URI Formats
The SDK supports multiple image URI formats:
| Format | Example | Use Case |
|--------|---------|----------|
| File URI | file:///var/mobile/... | Images from device storage |
| Data URI | data:image/jpeg;base64,... | Base64 encoded images |
| HTTP/HTTPS | https://example.com/image.jpg | Remote images |
Recommendation: Use file:// URIs for best performance. Remote URLs are fetched synchronously and may cause UI blocking.
🎯 Getting Your API Key and Model
- Sign up at roboflow.com
- Create or upload a dataset
- Train a model or use a pre-trained one from Roboflow Universe
- Get your API key from Settings → Roboflow API
- Find your model ID and version in the model details page
⚙️ Configuration
Confidence Threshold
Controls the minimum confidence score for detections:
// Only show predictions with 70% confidence or higher
const result = await Roboflow.detectObjects(imageUri);Overlap Threshold (IoU)
Controls how much bounding boxes can overlap before one is removed:
// More aggressive non-max suppression (removes more overlapping boxes)
const result = await Roboflow.detectObjects(imageUri);Max Detections
Limits the number of detections returned:
// Return at most 10 detections
const result = await Roboflow.detectObjects(imageUri);🏗️ Architecture
This package uses Turbo Modules for optimal performance:
Old Architecture (< RN 0.68):
JavaScript → JSON Bridge → Native Code- Serializes data to JSON
- Asynchronous by default
- Works but slower
New Architecture (>= RN 0.68):
JavaScript → JSI (Direct) → Native Code- Direct C++ bindings via JSI
- No JSON serialization overhead
- ~30% faster for inference calls
- Type-safe at compile time
The package automatically uses the best architecture available!
🚀 Performance
Performance characteristics on iPhone 12:
| Operation | Time | Notes | |-----------|------|-------| | Initialize | ~100ms | One-time setup | | Load Model (first time) | ~2-5s | Downloads and caches | | Load Model (cached) | ~500ms | Loads from local cache | | Inference (640x640 image) | ~100-300ms | Depends on model complexity |
Tips for better performance:
- Load models once during app startup
- Cache model locally (automatic)
- Use smaller image resolutions
- Reduce
maxDetectionsif you don't need many
📱 Platform Support
| Platform | Status | |----------|--------| | iOS | ✅ Fully supported (15.4+) | | Android | ⏳ Coming soon |
🐛 Troubleshooting
"RoboflowRN module is not available"
Solution:
cd ios
rm -rf Pods Podfile.lock build
pod install
cd ..
npx react-native run-ios"Failed to load model"
Possible causes:
- Invalid API key
- Model ID or version doesn't exist
- Network connection issues (first-time download)
- Insufficient device storage
Solution: Check your API key and model ID in the Roboflow dashboard
"Image loading failed"
Possible causes:
- Invalid URI format
- File doesn't exist
- Unsupported image format
Solution: Verify the URI and ensure the image exists. Use file:// URIs for local files.
Build errors after installation
Solution:
# Clean everything
cd ios
rm -rf ~/Library/Developer/Xcode/DerivedData
rm -rf Pods Podfile.lock build
pod install --repo-update
cd ..
# Rebuild
npx react-native run-iosModel takes too long to load
First-time: Model is being downloaded. Subsequent loads will be instant (cached locally).
Always slow: Check device storage and network connection.
🧪 Testing
import Roboflow from 'react-native-cogni-vision-rnroboflow';
describe('Roboflow SDK', () => {
it('should initialize successfully', async () => {
await expect(
Roboflow.initialize('test_api_key')
).resolves.not.toThrow();
});
it('should detect initialization state', () => {
expect(Roboflow.isInitialized()).toBe(false);
});
});📄 TypeScript
Full TypeScript support with type definitions:
import Roboflow, {
Prediction,
DetectionResult,
ModelInfo,
DetectionOptions
} from 'react-native-cogni-vision-rnroboflow';
const options: DetectionOptions = {
confidence: 0.5,
overlap: 0.5,
maxDetections: 100
};
const result: DetectionResult = await Roboflow.detectObjects(uri);
const predictions: Prediction[] = result.predictions;🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 License
MIT License - see LICENSE file for details
🔗 Links
🙏 Credits
Built with ❤️ using:
📮 Support
- For SDK issues: Open a GitHub issue
- For Roboflow platform issues: Roboflow Support
- For general questions: GitHub Discussions
Made with ⚡️ and ☕️
If you find this package useful, please consider giving it a ⭐️ on GitHub!
