Cutouts · Labels · OCR — Vision on iOS, ML Kit on Android, built with Nitro Modules.
npm install react-native-nitro-vision-kit react-native-nitro-modules
cd ios && pod install| Minimum | |
|---|---|
| React Native | 0.75 |
react-native-nitro-modules |
0.36.0 |
| iOS | 13 · cutouts 17+ · OCR 18+ |
| Android | API 24 |
Requires the New Architecture.
import { VisionKit } from 'react-native-nitro-vision-kit'Cutout:
if (!VisionKit.capabilities.supportsBackgroundRemoval) {
throw new Error(VisionKit.capabilities.backgroundRemovalUnavailableReason)
}
const cutout = await VisionKit.removeBackground(imagePath, { trim: true })
const path = await cutout.saveToTemporaryFile('png', 100)
cutout.dispose()Labels:
const labels = await VisionKit.classifyImage(imagePath, {
maxResults: 5,
minConfidence: 0.5,
})OCR:
const ocr = await VisionKit.readText(imagePath)
console.log(ocr.text)
ocr.dispose()All three at once:
const result = await VisionKit.analyzeImage(imagePath, {
removeBackground: { trim: true },
classify: { maxResults: 5 },
readText: {},
})
result.segmentation?.dispose()
result.text?.dispose()VisionKit.capabilities
| Field | Meaning |
|---|---|
supportsBackgroundRemoval |
Cutouts available |
backgroundRemovalUnavailableReason |
Why not |
supportsImageClassification |
Labels available |
supportsTextRecognition |
OCR available |
supportedTextLanguages |
Language tags you can request |
Returns a cutout HybridObject. iOS 17+, Android API 24+ with Play Services (ML Kit subject segmentation, beta).
Export via saveToTemporaryFile(format, quality), toArrayBuffer(), or toMaskBuffer().
Options & result fields
| Option | Default | Meaning |
|---|---|---|
trim |
true |
Crop to the subject |
maxPixels |
6_000_000 |
Cap when loading the image |
retainMask |
false |
Keep mask for toMaskBuffer() |
Result: width, height, bounds (VisionRect, 0–1), pixelBounds, foregroundCoverage, centroid, instanceCount, hasMask, sourceWidth, sourceHeight, trimOrigin.
Returns { label, confidence, index }[], highest confidence first. iOS 13+; on Android the model ships with the library.
Options
| Option | Default | Meaning |
|---|---|---|
maxResults |
0 |
0 keeps all above the score floor |
minConfidence |
0.5 |
Lowest score to keep |
region |
full image | VisionRect (0–1) |
Returns a text HybridObject. Prefer text and blockAt(i) — blocks copies everything into JS. iOS 18+ (RecognizeTextRequest); Android uses Play Services script models (Latin, Chinese, Japanese, Korean, Devanagari).
Image load cap: 4M pixels on both platforms; on Android the longest side is also capped at 2048.
Options & platform quirks
| Option | Default | Platform |
|---|---|---|
languages |
auto / Latin | Both |
recognitionLevel |
accurate |
iOS |
region |
full image | Both (VisionRect) |
minTextHeightFraction |
unset | Both |
usesLanguageCorrection |
true |
iOS |
customWords |
unset | iOS |
maxCandidates |
1 |
iOS (1–10) |
Android: languages selects script models. Non-Latin models also read Latin; multiple non-Latin scripts can run together. A block may contain many lines.
iOS: each block is one line.
One decode. Pass at least one of removeBackground, classify, or readText.
- No subject found →
segmentationomitted; labels and text still run. - If classify/OCR omit
regionand a cutout ran → subject bounds are used.
classifyImage works offline out of the box (model is packaged). removeBackground and readText download a Play Services model once — allow up to ~2 minutes online on first use; offline with no model fails immediately. iOS ships its models with the OS.
Absolute paths and file:// work everywhere. content:// is Android-only.
Only pass paths created by your app — native code opens the path and returns pixels/text to JavaScript.
cd example
npm install
cd ios && bundle install && bundle exec pod install && cd ..
npm run ios # or: npm run androidAfter a cutout, Keep saves to Photos.

