plant-health-lib
v1.0.1
Published
A comprehensive React Native library for plant disease detection using TensorFlow Lite
Maintainers
Readme
🌿 plant-health-lib
A comprehensive React Native library for on-device plant disease detection. Point the camera at a leaf (or upload a photo) and a quantized TFLite model classifies 38+ crop diseases — fully offline, no backend.
Installation
npm install plant-health-lib
# or
yarn add plant-health-libQuick Start
Complete UI (One-liner setup)
import { UI } from 'plant-health-lib';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<SafeAreaProvider>
<UI.HistoryProvider>
<UI.RootNavigator />
</UI.HistoryProvider>
</SafeAreaProvider>
</GestureHandlerRootView>
);
}Building Custom UI
import { useFrameClassifier, useHistory } from 'plant-health-lib/hooks';
import { getDiseaseInfo } from 'plant-health-lib/services';
import { classifyImage } from 'plant-health-lib/utils';Features
- ✅ 38+ Disease Classes – Comprehensive crop disease database
- ✅ TensorFlow Lite Integration – Fast GPU-accelerated inference
- ✅ Live Camera Detection – Real-time classification from camera frames
- ✅ Offline Operation – No backend required, fully on-device
- ✅ TypeScript Support – Full type safety included
- ✅ History Tracking – AsyncStorage-backed scan history
Stack
| Concern | Library |
|---|---|
| AI inference | react-native-fast-tflite (GPU/CoreML delegates) |
| Camera + live frames | react-native-vision-camera + vision-camera-resize-plugin |
| Frame-processor threading | react-native-worklets-core, react-native-reanimated |
| Navigation | @react-navigation/native-stack |
| Persistence | @react-native-async-storage/async-storage |
| Gallery upload | react-native-image-picker |
Architecture
App.tsx warms up the model on launch
src/
navigation/RootNavigator Home → Scan → Result, + History
screens/
HomeScreen dashboard, recent scans, entry points
ScanScreen live camera w/ throttled frame classification + capture/upload
ResultScreen diagnosis, confidence, treatment, prevention, top-K
HistoryScreen saved scans
services/
classifier.ts loads .tflite, normalizes input, runs inference, softmax + top-K
diseaseData.ts 38-class label map + remedy/prevention knowledge base
hooks/
useFrameClassifier.ts vision-camera frame processor → resize (GPU) → TFLite on worklet
useHistory.ts AsyncStorage-backed scan history
utils/imageToTensor.ts still-image decode + resize to 224×224×3
components/ui.tsx Card, Button, SeverityBadge, ConfidenceBar
theme/ design tokensTwo inference paths: live camera frames run through the GPU resize plugin inside a worklet (fast, ~1 fps throttled); still captures/uploads go through imageToTensor. Both feed the same classifier.classify().
Usage
Using the Complete UI (Recommended)
The library exports complete screens ready to use. Just wrap your app with the providers:
import { UI } from 'plant-health-lib';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<SafeAreaProvider>
<UI.HistoryProvider>
<UI.RootNavigator />
</UI.HistoryProvider>
</SafeAreaProvider>
</GestureHandlerRootView>
);
}Using Individual Screens
import {
HomeScreen,
ScanScreen,
ResultScreen,
HistoryScreen,
RootNavigator,
HistoryProvider
} from 'plant-health-lib/screens';Using the Frame Classifier Hook (Live Camera)
import { useFrameClassifier } from 'plant-health-lib/hooks';
import { getDiseaseInfo } from 'plant-health-lib/services';
export function ScanComponent() {
const { classify, isLoading, lastResult } = useFrameClassifier();
useEffect(() => {
if (lastResult) {
const disease = getDiseaseInfo(lastResult.label);
console.log(`Detected: ${disease.name} (${lastResult.confidence}%)`);
}
}, [lastResult]);
return (
<CameraView
onFrame={(frame) => classify(frame)}
// ... camera props
/>
);
}Using the History Hook
import { useHistory } from 'plant-health-lib/hooks';
const { scans, addScan, clearHistory } = useHistory();Classifying Images
import { classifyImage } from 'plant-health-lib/utils';
import { classifier } from 'plant-health-lib/services';
const result = await classifyImage(imagePath);
// result: { label: string; confidence: number; }API Reference
Hooks
useFrameClassifier()– Real-time frame classification from camera- Returns:
{ classify(frame), isLoading, lastResult }
- Returns:
useHistory()– Manage scan history with AsyncStorage- Returns:
{ scans, addScan(result), clearHistory() }
- Returns:
Services
classifier.classify(tensor)– Classify a TensorFlow tensorgetDiseaseInfo(label)– Get remedy/prevention data for a disease
Utils
classifyImage(path)– Load and classify a still image from file path
Components
<Card />– Styled card component<Button />– Button component<SeverityBadge />– Disease severity indicator<ConfidenceBar />– Confidence visualization
UI Screens (from plant-health-lib/screens or plant-health-lib/UI)
RootNavigator– Complete navigation stack (Home → Scan → Result → History)HomeScreen– Dashboard with scan entry points and recent scansScanScreen– Live camera detection UIResultScreen– Diagnosis, treatment, and prevention displayHistoryScreen– Saved scans list
UI Convenience Module
import { UI } from 'plant-health-lib';
// UI.HistoryProvider - Context provider for history management
// UI.RootNavigator - Full app navigator
// UI.HomeScreen, UI.ScanScreen, UI.ResultScreen, UI.HistoryScreen
// UI.useHistory, UI.useFrameClassifier, UI.classifier, UI.getDiseaseInfoSetting Up the Model
The library expects src/assets/plant_disease_model.tflite:
- Input:
[1, 224, 224, 3]float32 - Output:
[1, 38](logits or probabilities) - Labels: Must match
LABELSinsrc/services/diseaseData.ts
Train on PlantVillage dataset using MobileNetV2 or EfficientNet-Lite, then convert with TFLite converter. See src/assets/README.md for details.
Building from Source
npm install
npm run buildThe compiled library will be in lib/.
Contributing
We welcome contributions! Please feel free to submit a Pull Request.
License
MIT
Notes / Production Hardening
- The remedy text is general guidance — maintain an on-screen disclaimer; it's not a substitute for professional agricultural advice.
- For production, replace the JS image resampler with a native bitmap decoder for better performance.
- Tune
MEAN/STDinclassifier.tsto match your training normalization.
