diff --git a/skills/react-native-executorch/references/core-utilities.md b/skills/react-native-executorch/references/core-utilities.md
index 9b5a0c18b..cc455ace7 100644
--- a/skills/react-native-executorch/references/core-utilities.md
+++ b/skills/react-native-executorch/references/core-utilities.md
@@ -88,15 +88,33 @@ const runInference = async () => {
**Use cases:** Download management, storage cleanup, progress tracking, offline-first apps.
+## Built-in adapters vs custom adapter
+
+React Native ExecuTorch does not bundle a resource fetcher — you bring your own. Two ready-made adapters are provided:
+
+- **`ExpoResourceFetcher`** from `react-native-executorch-expo-resource-fetcher` — for Expo projects
+- **`BareResourceFetcher`** from `react-native-executorch-bare-resource-fetcher` — for bare React Native projects
+
+Register the adapter once at app startup before using any hooks or modules:
+
+```typescript
+import { initExecutorch } from 'react-native-executorch';
+import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
+
+initExecutorch({ resourceFetcher: ExpoResourceFetcher });
+```
+
+If neither adapter fits your needs (custom download library, private server, custom caching), you can implement the `ResourceFetcherAdapter` interface yourself. See [Custom Adapter](https://docs.swmansion.com/react-native-executorch/docs/resource-fetcher/custom-adapter) for details.
+
## Basic Usage
```typescript
-import { ResourceFetcher } from 'react-native-executorch';
+import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
// Download multiple resources with progress tracking
const downloadModels = async () => {
try {
- const uris = await ResourceFetcher.fetch(
+ const uris = await ExpoResourceFetcher.fetch(
(progress) =>
console.log(`Download progress: ${(progress * 100).toFixed(1)}%`),
'https://example.com/llama3_2.pte',
@@ -117,22 +135,22 @@ const downloadModels = async () => {
## Pause and Resume Downloads
```typescript
-import { ResourceFetcher } from 'react-native-executorch';
+import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
-const uris = ResourceFetcher.fetch(
+const uris = ExpoResourceFetcher.fetch(
(progress) => console.log('Total progress:', progress),
'https://.../llama3_2.pte',
'https://.../qwen3.pte'
).then((uris) => {
- console.log('URI resolved as: ', uris); // since we pause the fetch, uris is resolved to null
+ console.log('URI resolved as: ', uris); // null, since we paused
});
-await ResourceFetcher.pauseFetching(
+await ExpoResourceFetcher.pauseFetching(
'https://.../llama3_2.pte',
'https://.../qwen3.pte'
);
-const resolvedUris = await ResourceFetcher.resumeFetching(
+const resolvedUris = await ExpoResourceFetcher.resumeFetching(
'https://.../llama3_2.pte',
'https://.../qwen3.pte'
);
@@ -141,17 +159,17 @@ const resolvedUris = await ResourceFetcher.resumeFetching(
## Cancel Downloads
```typescript
-import { ResourceFetcher } from 'react-native-executorch';
+import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
-const uris = ResourceFetcher.fetch(
+const uris = ExpoResourceFetcher.fetch(
(progress) => console.log('Total progress:', progress),
'https://.../llama3_2.pte',
'https://.../qwen3.pte'
).then((uris) => {
- console.log('URI resolved as: ', uris); // since we cancel the fetch, uris is resolved to null
+ console.log('URI resolved as: ', uris); // null, since we cancelled
});
-await ResourceFetcher.cancelFetching(
+await ExpoResourceFetcher.cancelFetching(
'https://.../llama3_2.pte',
'https://.../qwen3.pte'
);
@@ -160,22 +178,22 @@ await ResourceFetcher.cancelFetching(
## Manage Downloaded Resources
```typescript
-import { ResourceFetcher } from 'react-native-executorch';
+import { ExpoResourceFetcher } from 'react-native-executorch-expo-resource-fetcher';
// List all downloaded files
const listFiles = async () => {
- const files = await ResourceFetcher.listDownloadedFiles();
+ const files = await ExpoResourceFetcher.listDownloadedFiles();
console.log('All downloaded files:', files);
- const models = await ResourceFetcher.listDownloadedModels();
+ const models = await ExpoResourceFetcher.listDownloadedModels();
console.log('Model files:', models);
};
// Clean up old resources
const cleanup = async () => {
- const oldModelUrl = 'https://example.com/old_model.pte';
-
- await ResourceFetcher.deleteResources(oldModelUrl);
+ await ExpoResourceFetcher.deleteResources(
+ 'https://example.com/old_model.pte'
+ );
console.log('Old model deleted');
};
```
@@ -195,11 +213,12 @@ Resources can be:
**Progress callback:** Progress is reported as 0-1 for all downloads combined.
**Null return:** If `fetch()` returns `null`, download was paused or cancelled.
**Network errors:** Implement retry logic with exponential backoff for reliability.
-**Storage location:** Downloaded files are stored in application's document directory under `react-native-executorch/`
+**Pause/resume on Android:** `BareResourceFetcher` does not support pause/resume on Android. Use `ExpoResourceFetcher` if you need this on Android.
## Additional references
-- [ResourceFetcher full reference docs](https://docs.swmansion.com/react-native-executorch/docs/utilities/resource-fetcher)
+- [ResourceFetcher usage docs](https://docs.swmansion.com/react-native-executorch/docs/resource-fetcher/usage)
+- [Custom Adapter docs](https://docs.swmansion.com/react-native-executorch/docs/resource-fetcher/custom-adapter)
- [Loading Models guide](https://docs.swmansion.com/react-native-executorch/docs/fundamentals/loading-models)
---
@@ -220,13 +239,13 @@ import {
RnExecutorchErrorCode,
} from 'react-native-executorch';
-const llm = new LLMModule({
- tokenCallback: (token) => console.log(token),
- messageHistoryCallback: (messages) => console.log(messages),
-});
-
try {
- await llm.load(LLAMA3_2_1B_QLORA, (progress) => console.log(progress));
+ const llm = await LLMModule.fromModelName(
+ LLAMA3_2_1B_QLORA,
+ (progress) => console.log(progress),
+ (token) => console.log(token),
+ (messages) => console.log(messages)
+ );
await llm.sendMessage('Hello!');
} catch (err) {
if (err instanceof RnExecutorchError) {
@@ -242,21 +261,27 @@ try {
```typescript
import {
+ LLMModule,
+ LLAMA3_2_1B_QLORA,
RnExecutorchError,
RnExecutorchErrorCode,
} from 'react-native-executorch';
-const handleModelError = async (llm, message: string) => {
+const llm = await LLMModule.fromModelName(
+ LLAMA3_2_1B_QLORA,
+ (progress) => console.log(progress),
+ (token) => console.log(token),
+ (messages) => console.log(messages)
+);
+
+const handleModelError = async (message: string) => {
try {
await llm.sendMessage(message);
} catch (err) {
if (err instanceof RnExecutorchError) {
switch (err.code) {
case RnExecutorchErrorCode.ModuleNotLoaded:
- console.error('Model not loaded. Loading now...');
- await llm.load(LLAMA3_2_1B_QLORA);
- // Retry the message
- await llm.sendMessage(message);
+ console.error('Model not loaded.');
break;
case RnExecutorchErrorCode.ModelGenerating:
@@ -267,7 +292,9 @@ const handleModelError = async (llm, message: string) => {
case RnExecutorchErrorCode.InvalidConfig:
console.error('Invalid configuration:', err.message);
// Reset to default config
- await llm.configure({ topp: 0.9, temperature: 0.7 });
+ await llm.configure({
+ generationConfig: { topp: 0.9, temperature: 0.7 },
+ });
break;
default:
diff --git a/skills/react-native-executorch/references/reference-audio.md b/skills/react-native-executorch/references/reference-audio.md
index 50bb60c13..8b66e953d 100644
--- a/skills/react-native-executorch/references/reference-audio.md
+++ b/skills/react-native-executorch/references/reference-audio.md
@@ -13,16 +13,27 @@ description: Reference for using Speech to Text, Text to Speech and Voice Activi
```typescript
import { useSpeechToText, WHISPER_TINY_EN } from 'react-native-executorch';
import { AudioContext } from 'react-native-audio-api';
+import * as FileSystem from 'expo-file-system';
+
+const model = useSpeechToText({
+ model: WHISPER_TINY_EN,
+});
-const model = useSpeechToText({ model: WHISPER_TINY_EN });
+const { uri } = await FileSystem.downloadAsync(
+ 'https://some-audio-url.com/file.mp3',
+ FileSystem.cacheDirectory + 'audio_file'
+);
-// Process audio file
const audioContext = new AudioContext({ sampleRate: 16000 });
-const decodedAudio = await audioContext.decodeAudioDataSource(audioUri);
-const waveform = decodedAudio.getChannelData(0);
+const decodedAudioData = await audioContext.decodeAudioData(uri);
+const audioBuffer = decodedAudioData.getChannelData(0);
-const transcription = await model.transcribe(waveform);
-console.log(transcription);
+try {
+ const transcription = await model.transcribe(audioBuffer);
+ console.log(transcription.text);
+} catch (error) {
+ console.error('Error during audio transcription', error);
+}
```
## Multilingual Transcription
@@ -38,31 +49,142 @@ const transcription = await model.transcribe(spanishAudio, {
});
```
-## Streaming Transcription
+## Timestamps & Transcription Stat Data
+
+You can obtain word-level timestamps and other useful parameters from transcription by setting `verbose: true` in the options:
```typescript
-import { AudioRecorder, AudioManager } from 'react-native-audio-api';
+const transcription = await model.transcribe(audioBuffer, { verbose: true });
+// Example result
+// {
+// task: "transcription",
+// text: "Example text for a ...",
+// duration: 9.05,
+// language: "en",
+// segments: [
+// {
+// start: 0,
+// end: 5.4,
+// text: "Example text for",
+// words: [
+// {
+// word: "Example",
+// start: 0,
+// end: 1.4
+// },
+// ...
+// ],
+// tokens: [1, 32, 45, ...],
+// temperature: 0.0,
+// avgLogProb: -1.235,
+// compressionRatio: 1.632
+// },
+// ...
+// ]
+// }
+```
-const recorder = new AudioRecorder({
- sampleRate: 16000,
- bufferLengthInSamples: 1600,
-});
+## Streaming Transcription
-// Start streaming
-recorder.onAudioReady(({ buffer }) => {
- model.streamInsert(buffer.getChannelData(0));
-});
-recorder.start();
+For audio longer than 30 seconds, use streaming transcription with the whisper-streaming algorithm. This intelligently chunks audio to avoid cutting speech mid-sentence:
+
+```tsx
+import React, { useEffect, useState, useRef } from 'react';
+import { Text, Button, View, SafeAreaView } from 'react-native';
+import { useSpeechToText, WHISPER_TINY_EN } from 'react-native-executorch';
+import { AudioManager, AudioRecorder } from 'react-native-audio-api';
+
+export default function App() {
+ const model = useSpeechToText({
+ model: WHISPER_TINY_EN,
+ });
+
+ const [transcribedText, setTranscribedText] = useState('');
+
+ const isRecordingRef = useRef(false);
+
+ const [recorder] = useState(() => new AudioRecorder());
+
+ useEffect(() => {
+ AudioManager.setAudioSessionOptions({
+ iosCategory: 'playAndRecord',
+ iosMode: 'spokenAudio',
+ iosOptions: ['allowBluetooth', 'defaultToSpeaker'],
+ });
+ AudioManager.requestRecordingPermissions();
+ }, []);
+
+ const handleStartStreamingTranscribe = async () => {
+ isRecordingRef.current = true;
+ setTranscribedText('');
+
+ const sampleRate = 16000;
+
+ recorder.onAudioReady(
+ {
+ sampleRate,
+ bufferLength: 0.1 * sampleRate,
+ channelCount: 1,
+ },
+ (chunk) => {
+ model.streamInsert(chunk.buffer.getChannelData(0));
+ }
+ );
+
+ try {
+ await recorder.start();
+ } catch (e) {
+ console.error('Recorder failed:', e);
+ return;
+ }
+
+ try {
+ let accumulatedCommitted = '';
-await model.stream();
+ const streamIter = model.stream({ verbose: false });
+
+ for await (const { committed, nonCommitted } of streamIter) {
+ if (!isRecordingRef.current) break;
+
+ if (committed.text) {
+ accumulatedCommitted += committed.text;
+ }
+
+ setTranscribedText(accumulatedCommitted + nonCommitted.text);
+ }
+ } catch (error) {
+ console.error('Error during streaming transcription:', error);
+ }
+ };
-// Access results
-console.log(model.committedTranscription);
-console.log(model.nonCommittedTranscription);
+ const handleStopStreamingTranscribe = () => {
+ isRecordingRef.current = false;
+ recorder.stop();
+ model.streamStop();
+ };
-// Stop streaming
-recorder.stop();
-model.streamStop();
+ return (
+
+
+
+ {transcribedText || 'Press start to speak...'}
+
+
+
+
+
+
+
+ );
+}
```
## Troubleshooting
@@ -103,8 +225,7 @@ const model = useTextToSpeech({
const audioContext = new AudioContext({ sampleRate: 24000 });
const handleSpeech = async (text: string) => {
- const speed = 1.0;
- const waveform = await model.forward(text, speed);
+ const waveform = await model.forward({ text, speed: 1.0 });
const audioBuffer = audioContext.createBuffer(1, waveform.length, 24000);
audioBuffer.getChannelData(0).set(waveform);
@@ -120,21 +241,43 @@ const handleSpeech = async (text: string) => {
```typescript
// Stream chunks for lower latency
-await tts.stream({
+await model.stream({
text: 'Long text to be streamed chunk by chunk...',
speed: 1.0,
+ onBegin: async () => console.log('Streaming started'),
onNext: async (chunk) => {
return new Promise((resolve) => {
- const buffer = ctx.createBuffer(1, chunk.length, 24000);
+ const buffer = audioContext.createBuffer(1, chunk.length, 24000);
buffer.getChannelData(0).set(chunk);
- const source = ctx.createBufferSource();
+ const source = audioContext.createBufferSource();
source.buffer = buffer;
- source.connect(ctx.destination);
+ source.connect(audioContext.destination);
source.onEnded = () => resolve();
source.start();
});
},
+ onEnd: async () => console.log('Streaming finished'),
+ stopAutomatically: true,
+});
+```
+
+## Phoneme-based synthesis
+
+If you have pre-computed phonemes, use `forwardFromPhonemes` or `streamFromPhonemes` to skip the text-to-phoneme step:
+
+```typescript
+const waveform = await model.forwardFromPhonemes({
+ phonemes: 'hɛloʊ',
+ speed: 1.0,
+});
+
+await model.streamFromPhonemes({
+ phonemes: 'hɛloʊ wɜːld',
+ speed: 1.0,
+ onNext: async (chunk) => {
+ /* play chunk */
+ },
});
```
@@ -146,17 +289,14 @@ For all available models check out [this exported HuggingFace models collection]
**Available Voices:**
-- `KOKORO_VOICE_AF_HEART` - Female, heart
-- `KOKORO_VOICE_AF_SKY` - Female, sky
-- `KOKORO_VOICE_AF_BELLA` - Female, bella
-- `KOKORO_VOICE_AF_NICOLE` - Female, nicole
-- `KOKORO_VOICE_AF_SARAH` - Female, sarah
-- `KOKORO_VOICE_AM_ADAM` - Male, adam
-- `KOKORO_VOICE_AM_MICHAEL` - Male, michael
+- `KOKORO_VOICE_AF_HEART` - American Female, heart
+- `KOKORO_VOICE_AF_RIVER` - American Female, river
+- `KOKORO_VOICE_AF_SARAH` - American Female, sarah
+- `KOKORO_VOICE_AM_ADAM` - American Male, adam
+- `KOKORO_VOICE_AM_MICHAEL` - American Male, michael
+- `KOKORO_VOICE_AM_SANTA` - American Male, santa
- `KOKORO_VOICE_BF_EMMA` - British Female, emma
-- `KOKORO_VOICE_BF_ISABELLA` - British Female, isabella
-- `KOKORO_VOICE_BM_GEORGE` - British Male, george
-- `KOKORO_VOICE_BM_LEWIS` - British Male, lewis
+- `KOKORO_VOICE_BM_DANIEL` - British Male, daniel
## Troubleshooting
diff --git a/skills/react-native-executorch/references/reference-cv-2.md b/skills/react-native-executorch/references/reference-cv-2.md
index 1c5b07d16..50415bd11 100644
--- a/skills/react-native-executorch/references/reference-cv-2.md
+++ b/skills/react-native-executorch/references/reference-cv-2.md
@@ -22,7 +22,11 @@ const model = useStyleTransfer({ model: STYLE_TRANSFER_CANDY });
const imageUri = 'file:///Users/.../photo.png';
try {
- const generatedImageUrl = await model.forward(imageUri);
+ // Returns PixelData (raw RGB buffer) by default
+ const pixelData = await model.forward(imageUri);
+
+ // Pass 'url' as second argument to get a file URI instead
+ const generatedImageUrl = await model.forward(imageUri, 'url');
console.log('Styled image:', generatedImageUrl);
} catch (error) {
console.error(error);
@@ -33,10 +37,10 @@ try {
**Model constants:**
-- `STYLE_TRANSFER_CANDY` - Candy artistic style
-- `STYLE_TRANSFER_MOSAIC` - Mosaic artistic style
-- `STYLE_TRANSFER_UDNIE` - Udnie artistic style
-- `STYLE_TRANSFER_RAIN_PRINCESS` - Rain princess artistic style
+- `STYLE_TRANSFER_CANDY` / `STYLE_TRANSFER_CANDY_QUANTIZED`
+- `STYLE_TRANSFER_MOSAIC` / `STYLE_TRANSFER_MOSAIC_QUANTIZED`
+- `STYLE_TRANSFER_UDNIE` / `STYLE_TRANSFER_UDNIE_QUANTIZED`
+- `STYLE_TRANSFER_RAIN_PRINCESS` / `STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED`
For the latest available models reference exported models in [HuggingFace Style Transfer collection](https://huggingface.co/collections/software-mansion/style-transfer)
@@ -101,7 +105,7 @@ function App() {
}
```
-**Model constants:** `BK_SDM_TINY_VPRED_256`
+**Model constants:** `BK_SDM_TINY_VPRED_256`, `BK_SDM_TINY_VPRED_512`
For the latest available models reference exported models in [HuggingFace Text to Image collection](https://huggingface.co/collections/software-mansion/text-to-image)
@@ -173,7 +177,7 @@ try {
## Available Models
-**Model constants:** `CLIP_VIT_BASE_PATCH32_IMAGE`
+**Model constants:** `CLIP_VIT_BASE_PATCH32_IMAGE`, `CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED`
For the latest available models reference exported models in [HuggingFace Image Embeddings collection](https://huggingface.co/collections/software-mansion/image-embeddings)
diff --git a/skills/react-native-executorch/references/reference-cv.md b/skills/react-native-executorch/references/reference-cv.md
index 3bb24acd0..76d738a5f 100644
--- a/skills/react-native-executorch/references/reference-cv.md
+++ b/skills/react-native-executorch/references/reference-cv.md
@@ -54,7 +54,7 @@ function App() {
## Available Models
-**Model constant:** `EFFICIENTNET_V2_S`
+**Model constants:** `EFFICIENTNET_V2_S`, `EFFICIENTNET_V2_S_QUANTIZED`
For the latest available models reference exported models in [HuggingFace Classification collection](https://huggingface.co/collections/software-mansion/classification)
@@ -109,15 +109,15 @@ const handleSegmentation = async (imageUri: string) => {
try {
const outputDict = await model.forward(
imageUri,
- [DeeplabLabel.CAT, DeeplabLabel.DOG, DeeplabLabel.PERSON],
+ ['CAT', 'DOG', 'PERSON'],
true
);
- const argmaxArray = outputDict[DeeplabLabel.ARGMAX];
+ const argmaxArray = outputDict['ARGMAX'];
- const catProbabilities = outputDict[DeeplabLabel.CAT];
- const dogProbabilities = outputDict[DeeplabLabel.DOG];
- const personProbabilities = outputDict[DeeplabLabel.PERSON];
+ const catProbabilities = outputDict['CAT'];
+ const dogProbabilities = outputDict['DOG'];
+ const personProbabilities = outputDict['PERSON'];
// ...
} catch (error) {
console.error(error);
@@ -127,20 +127,20 @@ const handleSegmentation = async (imageUri: string) => {
## Available Models
-**Model constant:** `DEEPLAB_V3_RESNET50`
+**Model constants:** `DEEPLAB_V3_RESNET50`, `DEEPLAB_V3_RESNET101`, `DEEPLAB_V3_MOBILENET_V3_LARGE`, `LRASPP_MOBILENET_V3_LARGE`, `FCN_RESNET50`, `FCN_RESNET101`, `SELFIE_SEGMENTATION` — plus quantized variants (e.g. `DEEPLAB_V3_RESNET50_QUANTIZED`)
For the latest available models check out exported models in [this HuggingFace Segmentation collection](https://huggingface.co/collections/software-mansion/image-segmentation)
## Troubleshooting
-**Performance:** Setting `resize=true` significantly increases processing time. Use `resize=false` for better performance when you don't need original image dimensions.
-**Memory usage:** Resize increases memory usage, especially with high-resolution images.
-**Pixel mapping:** When `resize=false`, pixel indices map to a 224x224 grid. When `resize=true`, indices map to original image dimensions.
+**Performance:** Setting `resizeToInput=true` significantly increases processing time. Use `resizeToInput=false` for better performance when you don't need original image dimensions.
+**Memory usage:** `resizeToInput` increases memory usage, especially with high-resolution images.
+**Pixel mapping:** When `resizeToInput=false`, pixel indices map to a 224x224 grid. When `resizeToInput=true`, indices map to original image dimensions.
## Additional references
-- [useSemanticSegmentation docs](https://docs.swmansion.com/react-native-executorch/docs/hooks/computer-vision/useImageSegmentation)
-- [useSemanticSegmentation API reference](https://docs.swmansion.com/react-native-executorch/docs/api-reference/functions/useImageSegmentation)
+- [useSemanticSegmentation docs](https://docs.swmansion.com/react-native-executorch/docs/hooks/computer-vision/useSemanticSegmentation)
+- [useSemanticSegmentation API reference](https://docs.swmansion.com/react-native-executorch/docs/api-reference/functions/useSemanticSegmentation)
- [HuggingFace Segmentation collection](https://huggingface.co/collections/software-mansion/image-segmentation)
- [Typescript API implementation of segmentation](https://docs.swmansion.com/react-native-executorch/docs/typescript-api/computer-vision/SemanticSegmentationModule)
@@ -155,12 +155,9 @@ For the latest available models check out exported models in [this HuggingFace S
## Basic Usage
```typescript
-import {
- useObjectDetection,
- SSDLITE_320_MOBILENET_V3_LARGE,
-} from 'react-native-executorch';
+import { useObjectDetection, YOLO26N } from 'react-native-executorch';
-const model = useObjectDetection({ model: SSDLITE_320_MOBILENET_V3_LARGE });
+const model = useObjectDetection({ model: YOLO26N });
try {
const detections = await model.forward('https://url-to-image.jpg');
@@ -175,6 +172,28 @@ try {
}
```
+## Detection Options
+
+`forward` accepts an optional second argument to tune inference:
+
+```typescript
+const detections = await model.forward('https://url-to-image.jpg', {
+ detectionThreshold: 0.5, // minimum confidence score (0-1)
+ iouThreshold: 0.45, // NMS IoU threshold (0-1)
+ inputSize: 640, // for YOLO multi-size models (e.g. 384, 512, 640)
+ classesOfInterest: ['PERSON', 'CAR'], // filter to specific classes only
+});
+```
+
+## Available Input Sizes (YOLO)
+
+YOLO models support multiple input sizes. Use `getAvailableInputSizes()` to query them:
+
+```typescript
+const sizes = model.getAvailableInputSizes();
+console.log(sizes); // e.g. [384, 512, 640]
+```
+
## Detection Object Structure
Each detection returned by `forward` has the following structure:
@@ -187,23 +206,23 @@ interface Bbox {
y2: number; // Top-right y coordinate
}
-interface Detection {
+interface Detection {
bbox: Bbox;
- label: keyof typeof CocoLabels; // Object class name
+ label: keyof L; // Object class name, defaults to CocoLabel keys
score: number; // Confidence score (0-1)
}
```
## Available Models
-**Model constant:** `SSDLITE_320_MOBILENET_V3_LARGE`
+**Model constants:** `YOLO26N`, `YOLO26S`, `YOLO26M`, `YOLO26L`, `YOLO26X`, `RF_DETR_NANO`, `SSDLITE_320_MOBILENET_V3_LARGE`
For the latest available models reference exported models in [HuggingFace Object Detection collection](https://huggingface.co/collections/software-mansion/object-detection)
## Troubleshooting
-**Multiple detections:** The model may detect the same object multiple times with slightly different bounding boxes. Consider implementing non-maximum suppression (NMS) if needed.
-**Confidence thresholds:** Adjust the confidence threshold based on your use case. Higher thresholds (>0.7) reduce false positives but may miss objects.
+**Multiple detections:** Use `iouThreshold` to tune NMS aggressiveness. Lower values merge more overlapping boxes.
+**Confidence thresholds:** Adjust `detectionThreshold` based on your use case. Higher values (>0.7) reduce false positives but may miss objects.
**Coordinate system:** Bounding box coordinates are in pixel space relative to the input image dimensions.
## Additional references
diff --git a/skills/react-native-executorch/references/reference-llms.md b/skills/react-native-executorch/references/reference-llms.md
index 0ef98298a..4c8041b66 100644
--- a/skills/react-native-executorch/references/reference-llms.md
+++ b/skills/react-native-executorch/references/reference-llms.md
@@ -12,15 +12,18 @@ description: Reference for using Large Language Models in React Native Executorc
## Basic Usage
```typescript
-import { useLLM, LLAMA3_2_1B } from 'react-native-executorch';
+import {
+ useLLM,
+ LFM2_5_1_2B_INSTRUCT_QUANTIZED,
+} from 'react-native-executorch';
-const llm = useLLM({ model: LLAMA3_2_1B });
+const llm = useLLM({ model: LFM2_5_1_2B_INSTRUCT_QUANTIZED });
```
## Functional Mode (Stateless)
```tsx
-const llm = useLLM({ model: LLAMA3_2_1B });
+const llm = useLLM({ model: LFM2_5_1_2B_INSTRUCT_QUANTIZED });
const handleGenerate = async () => {
const chat: Message[] = [
@@ -51,7 +54,6 @@ useEffect(() => {
llm.configure({
chatConfig: {
systemPrompt: 'You are a helpful assistant',
- contextStrategy: new SlidingWindowContextStrategy(512),
},
generationConfig: {
temperature: 0.7,
@@ -67,6 +69,81 @@ llm.sendMessage('Hello!');
console.log(llm.messageHistory);
```
+## Model configuration
+
+```tsx
+import { useEffect } from 'react';
+import {
+ MessageCountContextStrategy,
+ DEFAULT_SYSTEM_PROMPT,
+ ToolCall,
+ useLLM,
+ LFM2_5_1_2B_INSTRUCT_QUANTIZED,
+} from 'react-native-executorch';
+
+const TOOL_DEFINITIONS: LLMTool[] = [
+ {
+ name: 'get_weather',
+ description: 'Get/check weather in given location.',
+ parameters: {
+ type: 'dict',
+ properties: {
+ location: {
+ type: 'string',
+ description: 'Location where user wants to check weather',
+ },
+ },
+ required: ['location'],
+ },
+ },
+];
+
+const getWeather = async (_call: ToolCall) => {
+ return 'The weather is great!';
+};
+
+const executeTool: (call: ToolCall) => Promise = async (
+ call
+) => {
+ switch (call.toolName) {
+ case 'get_weather':
+ return await getWeather(call);
+ default:
+ console.error(`Wrong function! We don't handle it!`);
+ return null;
+ }
+};
+
+const llm = useLLM({ model: LFM2_5_1_2B_INSTRUCT_QUANTIZED });
+
+const { configure } = llm;
+useEffect(() => {
+ configure({
+ chatConfig: {
+ systemPrompt: `${DEFAULT_SYSTEM_PROMPT} Current time and date: ${new Date().toString()}`,
+ initialMessageHistory: [
+ {
+ role: 'user',
+ content: 'What is the current time and date?',
+ },
+ ],
+ contextStrategy: new MessageCountContextStrategy(6),
+ },
+ toolsConfig: {
+ tools: TOOL_DEFINITIONS,
+ executeToolCallback: executeTool,
+ displayToolCalls: true,
+ },
+ generationConfig: {
+ outputTokenBatchSize: 15,
+ batchTimeInterval: 100,
+ temperature: 0.7,
+ topp: 0.9,
+ },
+ });
+}, [configure]);
+```
+
## Tool Calling
```tsx
@@ -245,6 +322,58 @@ llm.interrupt();
}
```
+## Vision-Language Models (VLM)
+
+Some models support multimodal input — text and images together. The `capabilities` field on the model constant enables this.
+
+### Loading a VLM
+
+```tsx
+import { useLLM, LFM2_VL_1_6B_QUANTIZED } from 'react-native-executorch';
+
+const llm = useLLM({ model: LFM2_VL_1_6B_QUANTIZED });
+```
+
+### Sending a message with an image (Managed mode)
+
+```tsx
+const llm = useLLM({ model: LFM2_VL_1_6B_QUANTIZED });
+
+const send = () => {
+ llm.sendMessage('What is in this image?', {
+ imagePath: '/path/to/image.jpg',
+ });
+};
+
+return (
+
+
+ {llm.response}
+
+);
+```
+
+`imagePath` must be a local file path on the device.
+
+### Functional generation with images
+
+```tsx
+const llm = useLLM({ model: LFM2_VL_1_6B_QUANTIZED });
+
+const handleGenerate = async () => {
+ const chat: Message[] = [
+ {
+ role: 'user',
+ content: 'Describe this image.',
+ mediaPath: '/path/to/image.jpg',
+ },
+ ];
+
+ const response = await llm.generate(chat);
+ console.log(response);
+};
+```
+
## Troubleshooting
**Memory issues:** Use quantized models on lower-end devices - suggest smaller models as lower-end devices might not be able to fit LLMs into memory.
diff --git a/skills/react-native-executorch/references/reference-models.md b/skills/react-native-executorch/references/reference-models.md
index fe2170fa6..f6010a779 100644
--- a/skills/react-native-executorch/references/reference-models.md
+++ b/skills/react-native-executorch/references/reference-models.md
@@ -75,11 +75,25 @@ For a full list of available LLM models reference [HuggingFace LLMs collection](
[HuggingFace PHI 4 Mini Model](https://huggingface.co/software-mansion/react-native-executorch-phi-4-mini)
+### LFM2.5-1.2B-Instruct
+
+- **LFM2_5_1_2B_INSTRUCT** - LFM2.5 1.2B Instruct original (fp16)
+- **LFM2_5_1_2B_INSTRUCT_QUANTIZED** - LFM2.5 1.2B Instruct quantized (8da4w)
+
+[HuggingFace LFM2.5-1.2B-Instruct Model](https://huggingface.co/software-mansion/react-native-executorch-lfm2.5-1.2B-instruct)
+
+### LFM2.5-VL-1.6B (Vision-Language)
+
+- **LFM2_VL_1_6B_QUANTIZED** - LFM2.5 VL 1.6B quantized (8da4w), supports `capabilities: ['vision']`
+
+[HuggingFace LFM2.5-VL-1.6B Model](https://huggingface.co/software-mansion/react-native-executorch-lfm2.5-VL-1.6B)
+
---
## Image classification
- **EFFICIENTNET_V2_S** - [EfficientNet V2 S](https://huggingface.co/software-mansion/react-native-executorch-efficientnet-v2-s) (CoreML for iOS, XNNPACK for Android)
+- **EFFICIENTNET_V2_S_QUANTIZED** - EfficientNet V2 S quantized
For a list of all available Image Classification models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/classification).
@@ -87,18 +101,37 @@ For a list of all available Image Classification models reference [this Hugging
## Object detection
+- **YOLO26N** - YOLO26 Nano
+- **YOLO26S** - YOLO26 Small
+- **YOLO26M** - YOLO26 Medium
+- **YOLO26L** - YOLO26 Large
+- **YOLO26X** - YOLO26 XLarge
+- **RF_DETR_NANO** - [RF-DETR Nano](https://huggingface.co/software-mansion/react-native-executorch-rfdetr-nano-detector)
- **SSDLITE_320_MOBILENET_V3_LARGE** - [SSDLite 320 with MobileNet V3 Large](https://huggingface.co/software-mansion/react-native-executorch-ssdlite320-mobilenet-v3-large)
For a list of all available Object Detection models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/object-detection).
---
+## Instance segmentation
+
+- **YOLO26N_SEG** - YOLO26 Nano segmentation
+- **YOLO26S_SEG** - YOLO26 Small segmentation
+- **YOLO26M_SEG** - YOLO26 Medium segmentation
+- **YOLO26L_SEG** - YOLO26 Large segmentation
+- **YOLO26X_SEG** - YOLO26 XLarge segmentation
+- **RF_DETR_NANO_SEG** - RF-DETR Nano segmentation
+
+For a list of all available Instance Segmentation models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/object-detection).
+
+---
+
## Style transfer
-- **STYLE_TRANSFER_CANDY** - [Candy style](https://huggingface.co/software-mansion/react-native-executorch-style-transfer-candy)
-- **STYLE_TRANSFER_MOSAIC** - [Mosaic style](https://huggingface.co/software-mansion/react-native-executorch-style-transfer-mosaic)
-- **STYLE_TRANSFER_RAIN_PRINCESS** - [Rain Princess style](https://huggingface.co/software-mansion/react-native-executorch-style-transfer-rain-princess)
-- **STYLE_TRANSFER_UDNIE** - [Udnie style](https://huggingface.co/software-mansion/react-native-executorch-style-transfer-udnie)
+- **STYLE_TRANSFER_CANDY** / **STYLE_TRANSFER_CANDY_QUANTIZED**
+- **STYLE_TRANSFER_MOSAIC** / **STYLE_TRANSFER_MOSAIC_QUANTIZED**
+- **STYLE_TRANSFER_RAIN_PRINCESS** / **STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED**
+- **STYLE_TRANSFER_UDNIE** / **STYLE_TRANSFER_UDNIE_QUANTIZED**
For a list of all available Style Transfer models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/style-transfer).
@@ -106,24 +139,30 @@ For a list of all available Style Transfer models reference [this Hugging Face c
## OCR
-- **DETECTOR_CRAFT** - [CRAFT text detector](https://huggingface.co/software-mansion/react-native-executorch-detector-craft) - detects text regions in images
-- **RECOGNIZER_CRNN_EN** - [CRNN text recognizer](https://huggingface.co/software-mansion/react-native-executorch-recognizer-crnn.en) - recognizes English text
+Use language-specific constants like `OCR_ENGLISH`, `OCR_RUSSIAN`, `OCR_SIMPLIFIED_CHINESE`, etc. Each bundles the correct detector and recognizer internally. These are not composed from individually exported constants — use the `OCR_*` constants directly.
-For a list of all available OCR models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/ocr).
+For the full list of language constants and supported alphabets reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/ocr).
---
## Image embeddings
- **CLIP_VIT_BASE_PATCH32_IMAGE** - [CLIP ViT Base Patch32](https://huggingface.co/software-mansion/react-native-executorch-clip-vit-base-patch32) for image embeddings
+- **CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED** - CLIP ViT Base Patch32 quantized
For a list of all available Image embeddings models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/image-embeddings).
---
-## Image segmentation
+## Semantic segmentation
-- **DEEPLAB_V3_RESNET50** - [DeepLab V3](https://huggingface.co/software-mansion/react-native-executorch-deeplab-v3) with ResNet50 backbone
+- **DEEPLAB_V3_RESNET50** / **DEEPLAB_V3_RESNET50_QUANTIZED**
+- **DEEPLAB_V3_RESNET101** / **DEEPLAB_V3_RESNET101_QUANTIZED**
+- **DEEPLAB_V3_MOBILENET_V3_LARGE** / **DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED**
+- **LRASPP_MOBILENET_V3_LARGE** / **LRASPP_MOBILENET_V3_LARGE_QUANTIZED**
+- **FCN_RESNET50** / **FCN_RESNET50_QUANTIZED**
+- **FCN_RESNET101** / **FCN_RESNET101_QUANTIZED**
+- **SELFIE_SEGMENTATION** - person/background segmentation
For a list of all available Image Segmentation models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/image-segmentation).
@@ -132,6 +171,7 @@ For a list of all available Image Segmentation models reference [this Hugging Fa
## Text to image
- **BK_SDM_TINY_VPRED_256** - BK-SDM Tiny V-Pred (256x256 resolution)
+- **BK_SDM_TINY_VPRED_512** - BK-SDM Tiny V-Pred (512x512 resolution)
For a list of all available Text to Image models reference [this Hugging Face collection](https://huggingface.co/collections/software-mansion/text-to-image).
@@ -155,22 +195,18 @@ For a list of all available Speech to Text models reference [this Hugging Face c
### Whisper Models (English only)
-- **WHISPER_TINY_EN** - [Whisper Tiny](https://huggingface.co/software-mansion/react-native-executorch-whisper-tiny.en)
-- **WHISPER_TINY_EN_QUANTIZED** - [Whisper Tiny English-only (quantized)](https://huggingface.co/software-mansion/react-native-executorch-whisper-tiny-quantized.en)
-- **WHISPER_BASE_EN** - [Whisper Base](https://huggingface.co/software-mansion/react-native-executorch-whisper-base.en)
-- **WHISPER_SMALL_EN** - [Whisper Small](https://huggingface.co/software-mansion/react-native-executorch-whisper-small.en)
-- **WHISPER_MEDIUM_EN** - [Whisper Medium](https://huggingface.co/software-mansion/react-native-executorch-whisper-medium.en)
+- **WHISPER_TINY_EN** - Whisper Tiny English-only
+- **WHISPER_TINY_EN_QUANTIZED** - Whisper Tiny English-only quantized
+- **WHISPER_BASE_EN** - Whisper Base English-only
+- **WHISPER_BASE_EN_QUANTIZED** - Whisper Base English-only quantized
+- **WHISPER_SMALL_EN** - Whisper Small English-only
+- **WHISPER_SMALL_EN_QUANTIZED** - Whisper Small English-only quantized
### Whisper Models (Multilingual)
-- **WHISPER_TINY** - [Whisper Tiny multilingual](https://huggingface.co/software-mansion/react-native-executorch-whisper-tiny)
-- **WHISPER_BASE** - [Whisper Base multilingual](https://huggingface.co/software-mansion/react-native-executorch-whisper-base)
-- **WHISPER_SMALL** - [Whisper Small multilingual](https://huggingface.co/software-mansion/react-native-executorch-whisper-small)
-- **WHISPER_MEDIUM** - [Whisper Medium multilingual](https://huggingface.co/software-mansion/react-native-executorch-whisper-medium)
-
-### Other models
-
-- **MOONSHINE_TINY** - [Moonshine Tiny](https://huggingface.co/software-mansion/react-native-executorch-moonshine-tiny)
+- **WHISPER_TINY** - Whisper Tiny multilingual
+- **WHISPER_BASE** - Whisper Base multilingual
+- **WHISPER_SMALL** - Whisper Small multilingual
---
@@ -202,12 +238,12 @@ For a list of all available VAD models reference [this Hugging Face collection](
```typescript
import {
useLLM,
- LLAMA3_2_1B,
+ LFM2_5_1_2B_INSTRUCT_QUANTIZED,
QWEN3_1_7B_QUANTIZED,
} from 'react-native-executorch';
-const llama = useLLM(LLAMA3_2_1B);
-const qwen = useLLM(QWEN3_1_7B_QUANTIZED);
+const lfm = useLLM({ model: LFM2_5_1_2B_INSTRUCT_QUANTIZED });
+const qwen = useLLM({ model: QWEN3_1_7B_QUANTIZED });
```
---
diff --git a/skills/react-native-executorch/references/reference-nlp.md b/skills/react-native-executorch/references/reference-nlp.md
index 2052686bc..c0b9f5627 100644
--- a/skills/react-native-executorch/references/reference-nlp.md
+++ b/skills/react-native-executorch/references/reference-nlp.md
@@ -27,10 +27,10 @@ try {
## Example (computing similarity)
```typescript
-const dotProduct = (a: number[], b: number[]) =>
+const dotProduct = (a: Float32Array, b: Float32Array) =>
a.reduce((sum, val, i) => sum + val * b[i], 0);
-const cosineSimilarity = (a: number[], b: number[]) => {
+const cosineSimilarity = (a: Float32Array, b: Float32Array) => {
const dot = dotProduct(a, b);
const normA = Math.sqrt(dotProduct(a, a));
const normB = Math.sqrt(dotProduct(b, b));
diff --git a/skills/react-native-executorch/references/reference-ocr.md b/skills/react-native-executorch/references/reference-ocr.md
index 818478e57..61328df1f 100644
--- a/skills/react-native-executorch/references/reference-ocr.md
+++ b/skills/react-native-executorch/references/reference-ocr.md
@@ -46,31 +46,24 @@ The `bbox` array contains four points representing the corners of the detected t
## Language Support
-Different recognizer models support different alphabets and languages:
+Use the appropriate `OCR_*` language constant for your target language — each one bundles the correct detector and recognizer internally:
```typescript
import {
useOCR,
OCR_ENGLISH,
- RECOGNIZER_LATIN_CRNN,
- RECOGNIZER_CYRILLIC_CRNN,
- DETECTOR_CRAFT,
+ OCR_RUSSIAN,
+ OCR_GERMAN,
} from 'react-native-executorch';
-// For English (uses Latin alphabet)
const englishOCR = useOCR({ model: OCR_ENGLISH });
-
-// For custom language configuration
-const customOCR = useOCR({
- model: {
- detectorSource: DETECTOR_CRAFT,
- recognizerSource: RECOGNIZER_CYRILLIC_CRNN,
- language: 'ru', // Russian
- },
-});
+const russianOCR = useOCR({ model: OCR_RUSSIAN });
+const germanOCR = useOCR({ model: OCR_GERMAN });
```
-**Important:** The recognizer model must match the alphabet of your target language. For example, use `RECOGNIZER_LATIN_CRNN` for English, Polish, German, etc., and `RECOGNIZER_CYRILLIC_CRNN` for Russian, Ukrainian, etc.
+For the full list of supported language constants see [OCR Supported Alphabets](https://docs.swmansion.com/react-native-executorch/docs/api-reference#ocr-supported-alphabets).
+
+**Important:** The recognizer embedded in each constant is matched to the correct alphabet. Latin-alphabet languages (English, German, Polish, etc.) and Cyrillic-alphabet languages (Russian, Ukrainian, etc.) use different recognizer models — always use the matching `OCR_*` constant.
## Available Models
@@ -126,7 +119,7 @@ The `independentCharacters` parameter controls how text is processed:
```typescript
// Character mode - each character detected separately (better for CJK)
const charMode = useVerticalOCR({
- model: OCR_CHINESE,
+ model: OCR_SIMPLIFIED_CHINESE,
independentCharacters: true,
});