Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
228d6e2
feat(constants)!: switch URLs to v0.9.0 layout + add MODEL_REGISTRY
msluszniak May 13, 2026
b414030
fix(constants): split lfm-2.5 text/VL paths + colocate tokenizers
msluszniak May 13, 2026
e994cb0
docs(utilities): rewrite Model Registry page for the typed accessor
msluszniak May 13, 2026
61e25a6
refactor(apps): migrate example apps to MODEL_REGISTRY
msluszniak May 13, 2026
3cfdd22
fix(apps): compare picker entries by modelName to handle accessor fun…
msluszniak May 13, 2026
cc83335
feat(constants): wire up backend selection in MODEL_REGISTRY accessors
msluszniak May 13, 2026
fc5eeb0
feat(constants)!: default MODEL_REGISTRY accessors to the quantized v…
msluszniak May 14, 2026
d0982df
fix(constants): align URLs with v0.9.0 HF incompat fixes
msluszniak May 14, 2026
d849b0a
refactor(constants): rename BackendCell `default` -> `base`; fast-sam…
msluszniak May 14, 2026
7086044
refactor(constants): hoist multi-backend URLs to modelUrls.ts
msluszniak May 18, 2026
eff6ade
chore(constants): satisfy lint (jsdoc @param + prettier multi-line te…
msluszniak May 18, 2026
b7be456
refactor(registry)!: function-only lowercase \`models\`; add multimod…
msluszniak May 18, 2026
cf16a15
chore(apps): destructure heavily-used \`models\` groups for readability
msluszniak May 18, 2026
18810c4
fix(docs): repoint v0.8.x model-registry link from /next/ to its own …
msluszniak May 18, 2026
698ed7f
refactor(registry)!: rename `multimodal`→`lmm`; split `privacy_filter…
msluszniak May 19, 2026
bb81ac3
docs: migrate model-selection snippets to the `models` accessor
msluszniak May 19, 2026
737e18d
chore(constants): clear residual lint warnings
msluszniak May 19, 2026
6ba0a0a
refactor(registry)!: collapse `lmm` into `llm`
msluszniak May 19, 2026
5a357e7
docs(useLLM): collapse VLM rows into the aggregated LFM2.5 entry
msluszniak May 19, 2026
1917712
docs(useLLM): add Qwen 3.5 and Bielik v3.0 rows to Available Models
msluszniak May 19, 2026
18670f2
docs(webrtc): soften beta banner and add install tabs for peer deps
msluszniak May 19, 2026
8bf0010
fix(apps): default the LLM demo to LFM-2.5, not Llama 3.2
msluszniak May 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ module.exports = {
customWordListFile: path.resolve(__dirname, '.cspell-wordlist.txt'),
},
],
'camelcase': 'error',
// `properties: 'never'` lets the lowercase snake_case keys in `models`
// (e.g. `models.text_to_speech.kokoro_small`, mirroring the underlying
// `.pte` filenames) pass while still requiring camelCase for variable
// and function declarations.
'camelcase': ['error', { properties: 'never' }],
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-param': ['error', { checkDestructured: false }],
'jsdoc/check-param-names': ['error', { checkDestructured: false }],
Expand Down
10 changes: 4 additions & 6 deletions apps/bare-rn/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,7 @@ import {
TouchableWithoutFeedback,
View,
} from 'react-native';
import {
initExecutorch,
useLLM,
LLAMA3_2_1B_SPINQUANT,
} from 'react-native-executorch';
import { models, initExecutorch, useLLM } from 'react-native-executorch';
import { BareResourceFetcher } from 'react-native-executorch-bare-resource-fetcher';
import { setConfig } from '@kesha-antonov/react-native-background-downloader';
import { SafeAreaProvider, SafeAreaView } from 'react-native-safe-area-context';
Expand Down Expand Up @@ -144,7 +140,9 @@ function App() {
const textInputRef = useRef<TextInput>(null);
const scrollViewRef = useRef<ScrollView>(null);

const llm = useLLM({ model: LLAMA3_2_1B_SPINQUANT });
const llm = useLLM({
model: models.llm.lfm2_5_1_2b_instruct(),
});
Comment thread
msluszniak marked this conversation as resolved.
// Alternatively, to use a custom local model, uncomment below:
// const llm = useLLM({ model: {
// modelSource: require('./assets/ai-models/smolLm2/smolLm2_135M/smolLm2_135M_bf16.pte'),
Expand Down
16 changes: 11 additions & 5 deletions apps/computer-vision/app/classification/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import Spinner from '../../components/Spinner';
import { getImage } from '../../utils';
import {
models,
useClassification,
EFFICIENTNET_V2_S,
EFFICIENTNET_V2_S_QUANTIZED,
ClassificationModelSources,
} from 'react-native-executorch';
import { ModelPicker, ModelOption } from '../../components/ModelPicker';
const classification = models.classification;

const MODELS: ModelOption<ClassificationModelSources>[] = [
{ label: 'EfficientNet V2 S Quantized', value: EFFICIENTNET_V2_S_QUANTIZED },
{ label: 'EfficientNet V2 S', value: EFFICIENTNET_V2_S },
{
label: 'EfficientNet V2 S Quantized',
value: classification.efficientnet_v2_s(),
},
{
label: 'EfficientNet V2 S',
value: classification.efficientnet_v2_s({ quant: false }),
},
];
import { View, StyleSheet, Image, Text, ScrollView } from 'react-native';
import { BottomBar } from '../../components/BottomBar';
Expand All @@ -22,7 +28,7 @@ import ErrorBanner from '../../components/ErrorBanner';

export default function ClassificationScreen() {
const [selectedModel, setSelectedModel] =
useState<ClassificationModelSources>(EFFICIENTNET_V2_S_QUANTIZED);
useState<ClassificationModelSources>(classification.efficientnet_v2_s());
const [results, setResults] = useState<{ label: string; score: number }[]>(
[]
);
Expand Down
34 changes: 17 additions & 17 deletions apps/computer-vision/app/instance_segmentation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,9 @@ import { BottomBar } from '../../components/BottomBar';
import { getImage } from '../../utils';
import { ModelPicker, ModelOption } from '../../components/ModelPicker';
import {
models,
useInstanceSegmentation,
YOLO26N_SEG,
YOLO26S_SEG,
YOLO26M_SEG,
YOLO26L_SEG,
YOLO26X_SEG,
RF_DETR_NANO_SEG,
InstanceSegmentationModelSources,
FASTSAM_S,
FASTSAM_X,
} from 'react-native-executorch';
import {
View,
Expand All @@ -29,21 +22,28 @@ import ImageWithMasks, {
DisplayInstance,
} from '../../components/ImageWithMasks';
import { StatsBar } from '../../components/StatsBar';
const instanceSegmentation = models.instance_segmentation;
const objectDetection = models.object_detection;

const MODELS: ModelOption<InstanceSegmentationModelSources>[] = [
{ label: 'Yolo26N', value: YOLO26N_SEG },
{ label: 'Yolo26S', value: YOLO26S_SEG },
{ label: 'Yolo26M', value: YOLO26M_SEG },
{ label: 'Yolo26L', value: YOLO26L_SEG },
{ label: 'Yolo26X', value: YOLO26X_SEG },
{ label: 'RF-DeTR Nano', value: RF_DETR_NANO_SEG },
{ label: 'FastSAM-S', value: FASTSAM_S },
{ label: 'FastSAM-X', value: FASTSAM_X },
{ label: 'Yolo26N', value: instanceSegmentation.yolo26n_seg() },
{ label: 'Yolo26S', value: instanceSegmentation.yolo26s_seg() },
{ label: 'Yolo26M', value: instanceSegmentation.yolo26m_seg() },
{ label: 'Yolo26L', value: instanceSegmentation.yolo26l_seg() },
{ label: 'Yolo26X', value: instanceSegmentation.yolo26x_seg() },
{
label: 'RF-DeTR Nano',
value: instanceSegmentation.rf_detr_nano_seg(),
},
{ label: 'FastSAM-S', value: objectDetection.fastsam_s() },
{ label: 'FastSAM-X', value: objectDetection.fastsam_x() },
];

export default function InstanceSegmentationScreen() {
const [selectedModel, setSelectedModel] =
useState<InstanceSegmentationModelSources>(YOLO26N_SEG);
useState<InstanceSegmentationModelSources>(
instanceSegmentation.yolo26n_seg()
);
const [inferenceTime, setInferenceTime] = useState<number | null>(null);

const { setGlobalGenerating } = useContext(GeneratingContext);
Expand Down
31 changes: 16 additions & 15 deletions apps/computer-vision/app/object_detection/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,9 @@ import { BottomBar } from '../../components/BottomBar';
import { ModelPicker, ModelOption } from '../../components/ModelPicker';
import { getImage } from '../../utils';
import {
models,
Detection,
useObjectDetection,
RF_DETR_NANO,
SSDLITE_320_MOBILENET_V3_LARGE,
YOLO26N,
YOLO26S,
YOLO26M,
YOLO26L,
YOLO26X,
ObjectDetectionModelSources,
} from 'react-native-executorch';
import { View, StyleSheet, Image, Text } from 'react-native';
Expand All @@ -20,15 +14,22 @@ import React, { useContext, useEffect, useState } from 'react';
import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../ScreenWrapper';
import { StatsBar } from '../../components/StatsBar';
const objectDetection = models.object_detection;

const MODELS: ModelOption<ObjectDetectionModelSources>[] = [
{ label: 'RF-DeTR Nano', value: RF_DETR_NANO },
{ label: 'SSDLite MobileNet', value: SSDLITE_320_MOBILENET_V3_LARGE },
{ label: 'YOLO26N', value: YOLO26N },
{ label: 'YOLO26S', value: YOLO26S },
{ label: 'YOLO26M', value: YOLO26M },
{ label: 'YOLO26L', value: YOLO26L },
{ label: 'YOLO26X', value: YOLO26X },
{
label: 'RF-DeTR Nano',
value: objectDetection.rf_detr_nano(),
},
{
label: 'SSDLite MobileNet',
value: objectDetection.ssdlite_320_mobilenet_v3_large(),
},
{ label: 'YOLO26N', value: objectDetection.yolo26n() },
{ label: 'YOLO26S', value: objectDetection.yolo26s() },
{ label: 'YOLO26M', value: objectDetection.yolo26m() },
{ label: 'YOLO26L', value: objectDetection.yolo26l() },
{ label: 'YOLO26X', value: objectDetection.yolo26x() },
];
import ErrorBanner from '../../components/ErrorBanner';

Expand All @@ -41,7 +42,7 @@ export default function ObjectDetectionScreen() {
height: number;
}>();
const [selectedModel, setSelectedModel] =
useState<ObjectDetectionModelSources>(RF_DETR_NANO);
useState<ObjectDetectionModelSources>(objectDetection.rf_detr_nano());
const [inferenceTime, setInferenceTime] = useState<number | null>(null);

const model = useObjectDetection({ model: selectedModel });
Expand Down
4 changes: 2 additions & 2 deletions apps/computer-vision/app/pose_estimation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import Spinner from '../../components/Spinner';
import { BottomBar } from '../../components/BottomBar';
import { getImage } from '../../utils';
import {
models,
usePoseEstimation,
PoseDetections,
RnExecutorchError,
RnExecutorchErrorCode,
YOLO26N_POSE,
} from 'react-native-executorch';
import { View, StyleSheet, Image, Text } from 'react-native';
import React, { useContext, useEffect, useState } from 'react';
Expand All @@ -31,7 +31,7 @@ export default function PoseEstimationScreen() {
const [inferenceTime, setInferenceTime] = useState<number | null>(null);
const [layout, setLayout] = useState({ width: 0, height: 0 });

const model = usePoseEstimation({ model: YOLO26N_POSE });
const model = usePoseEstimation({ model: models.pose_estimation.yolo26n() });
const { setGlobalGenerating } = useContext(GeneratingContext);

useEffect(() => {
Expand Down
18 changes: 9 additions & 9 deletions apps/computer-vision/app/segment_anything/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,10 @@ import {
AlphaType,
} from '@shopify/react-native-skia';
import {
models,
useInstanceSegmentation,
useImageEmbeddings,
useTextEmbeddings,
FASTSAM_S,
FASTSAM_X,
CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED,
CLIP_VIT_BASE_PATCH32_TEXT,
InstanceSegmentationModelSources,
SegmentedInstance,
FastSAMLabel,
Expand All @@ -48,19 +45,20 @@ import ImageWithMasks, {
} from '../../components/ImageWithMasks';
import { getImage } from '../../utils';
import ColorPalette from '../../colors';
const objectDetection = models.object_detection;

type PromptMode = 'point' | 'box' | 'text';

const MODELS: ModelOption<InstanceSegmentationModelSources>[] = [
{ label: 'FastSAM-S', value: FASTSAM_S },
{ label: 'FastSAM-X', value: FASTSAM_X },
{ label: 'FastSAM-S', value: objectDetection.fastsam_s() },
{ label: 'FastSAM-X', value: objectDetection.fastsam_x() },
];

export default function SegmentAnythingScreen() {
const { setGlobalGenerating } = useContext(GeneratingContext);

const [selectedModel, setSelectedModel] =
useState<InstanceSegmentationModelSources>(FASTSAM_S);
useState<InstanceSegmentationModelSources>(objectDetection.fastsam_s());
const [mode, setMode] = useState<PromptMode>('point');
const [inferenceTime, setInferenceTime] = useState<number | null>(null);

Expand All @@ -78,9 +76,11 @@ export default function SegmentAnythingScreen() {
useInstanceSegmentation({ model: selectedModel });

const clipImage = useImageEmbeddings({
model: CLIP_VIT_BASE_PATCH32_IMAGE_QUANTIZED,
model: models.image_embedding.clip_vit_base_patch32_image(),
});
const clipText = useTextEmbeddings({
model: models.text_embedding.clip_vit_base_patch32_text(),
});
const clipText = useTextEmbeddings({ model: CLIP_VIT_BASE_PATCH32_TEXT });
const skiaSource = useImage(imageUri || null);

const [textPrompt, setTextPrompt] = useState('');
Expand Down
43 changes: 28 additions & 15 deletions apps/computer-vision/app/semantic_segmentation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,7 @@ import { BottomBar } from '../../components/BottomBar';
import { ModelPicker, ModelOption } from '../../components/ModelPicker';
import { getImage } from '../../utils';
import {
DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED,
DEEPLAB_V3_RESNET50_QUANTIZED,
DEEPLAB_V3_RESNET101_QUANTIZED,
LRASPP_MOBILENET_V3_LARGE_QUANTIZED,
FCN_RESNET50_QUANTIZED,
FCN_RESNET101_QUANTIZED,
SELFIE_SEGMENTATION,
models,
useSemanticSegmentation,
SemanticSegmentationModelSources,
} from 'react-native-executorch';
Expand All @@ -27,6 +21,7 @@ import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../ScreenWrapper';
import { StatsBar } from '../../components/StatsBar';
import ErrorBanner from '../../components/ErrorBanner';
const semanticSegmentation = models.semantic_segmentation;

const numberToColor: number[][] = [
[255, 87, 51], // 0 Red
Expand Down Expand Up @@ -55,21 +50,39 @@ const numberToColor: number[][] = [
const MODELS: ModelOption<SemanticSegmentationModelSources>[] = [
{
label: 'DeepLab MobileNet',
value: DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED,
value: semanticSegmentation.deeplab_v3_mobilenet_v3_large(),
},
{
label: 'DeepLab ResNet50',
value: semanticSegmentation.deeplab_v3_resnet50(),
},
{
label: 'DeepLab ResNet101',
value: semanticSegmentation.deeplab_v3_resnet101(),
},
{
label: 'LRASPP MobileNet',
value: semanticSegmentation.lraspp_mobilenet_v3_large(),
},
{
label: 'FCN ResNet50',
value: semanticSegmentation.fcn_resnet50(),
},
{
label: 'FCN ResNet101',
value: semanticSegmentation.fcn_resnet101(),
},
{
label: 'Selfie Segmentation',
value: semanticSegmentation.selfie_segmentation(),
},
{ label: 'DeepLab ResNet50', value: DEEPLAB_V3_RESNET50_QUANTIZED },
{ label: 'DeepLab ResNet101', value: DEEPLAB_V3_RESNET101_QUANTIZED },
{ label: 'LRASPP MobileNet', value: LRASPP_MOBILENET_V3_LARGE_QUANTIZED },
{ label: 'FCN ResNet50', value: FCN_RESNET50_QUANTIZED },
{ label: 'FCN ResNet101', value: FCN_RESNET101_QUANTIZED },
{ label: 'Selfie Segmentation', value: SELFIE_SEGMENTATION },
];

export default function SemanticSegmentationScreen() {
const { setGlobalGenerating } = useContext(GeneratingContext);
const [selectedModel, setSelectedModel] =
useState<SemanticSegmentationModelSources>(
DEEPLAB_V3_MOBILENET_V3_LARGE_QUANTIZED
semanticSegmentation.deeplab_v3_mobilenet_v3_large()
);

const {
Expand Down
19 changes: 10 additions & 9 deletions apps/computer-vision/app/style_transfer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,8 @@ import { BottomBar } from '../../components/BottomBar';
import { ModelPicker, ModelOption } from '../../components/ModelPicker';
import { getImage } from '../../utils';
import {
models,
useStyleTransfer,
STYLE_TRANSFER_CANDY_QUANTIZED,
STYLE_TRANSFER_MOSAIC_QUANTIZED,
STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED,
STYLE_TRANSFER_UDNIE_QUANTIZED,
StyleTransferModelName,
ResourceSource,
} from 'react-native-executorch';
Expand All @@ -18,23 +15,27 @@ import React, { useContext, useEffect, useState } from 'react';
import { GeneratingContext } from '../../context';
import ScreenWrapper from '../../ScreenWrapper';
import { StatsBar } from '../../components/StatsBar';
const styleTransfer = models.style_transfer;

type StyleTransferModelSources = {
modelName: StyleTransferModelName;
modelSource: ResourceSource;
};

const MODELS: ModelOption<StyleTransferModelSources>[] = [
{ label: 'Candy', value: STYLE_TRANSFER_CANDY_QUANTIZED },
{ label: 'Mosaic', value: STYLE_TRANSFER_MOSAIC_QUANTIZED },
{ label: 'Rain Princess', value: STYLE_TRANSFER_RAIN_PRINCESS_QUANTIZED },
{ label: 'Udnie', value: STYLE_TRANSFER_UDNIE_QUANTIZED },
{ label: 'Candy', value: styleTransfer.candy() },
{ label: 'Mosaic', value: styleTransfer.mosaic() },
{
label: 'Rain Princess',
value: styleTransfer.rain_princess(),
},
{ label: 'Udnie', value: styleTransfer.udnie() },
];
import ErrorBanner from '../../components/ErrorBanner';

export default function StyleTransferScreen() {
const [selectedModel, setSelectedModel] = useState<StyleTransferModelSources>(
STYLE_TRANSFER_CANDY_QUANTIZED
styleTransfer.candy()
);

const model = useStyleTransfer({ model: selectedModel });
Expand Down
Loading
Loading