Skip to content

feat: add bare React Native LLM chat example app#2

Open
rizalibnu wants to merge 66 commits into
feat/resource-fetcher-adaptersfrom
examples/bare-react-native
Open

feat: add bare React Native LLM chat example app#2
rizalibnu wants to merge 66 commits into
feat/resource-fetcher-adaptersfrom
examples/bare-react-native

Conversation

@rizalibnu

@rizalibnu rizalibnu commented Jan 27, 2026

Copy link
Copy Markdown
Owner

Description

Adds a new bare React Native example application demonstrating LLM chat functionality using Executorch. This example provides a complete reference implementation for running local LLM inference on mobile devices through a simple chat interface.

Key features:

  • Local LLM inference using Executorch
  • Simple chat UI with message history
  • Model loading and inference pipeline
  • Error handling and user feedback
  • Compatible with both iOS and Android

Introduces a breaking change?

  • Yes
  • No

Type of change

  • Bug fix (change which fixes an issue)
  • New feature (change which adds functionality)
  • Documentation update (improves or adds clarity to existing documentation)
  • Other (chores, tests, code style improvements etc.)

Tested on

  • iOS
  • Android

Testing instructions

  1. Navigate to the example directory:

cd examples/bare-react-native

  1. Install dependencies:

yarn install

  1. Run on iOS:

yarn ios

Or run on Android:

yarn android

  1. Verify the app launches and displays the chat interface

  2. Test message sending and model inference (requires model file setup)

Screenshots


Screenshot 2026-01-28 at 02 06 29

Related issues

Checklist

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have updated the documentation accordingly
  • My changes generate no new warnings

Additional notes

This example app was generated using npx @react-native-community/cli@latest init bare_rn --version 0.81.5 --pm yarn and follows bare React Native project structure (not Expo). It serves as a foundational example for developers to understand how to integrate Executorch for on-device LLM inference in their React Native applications.

Why this example is not included in the yarn workspace:

The bare React Native example is maintained outside the yarn workspace structure due to fundamental architectural differences and specific technical issues:

  1. Native Module Resolution Issues with Background Downloader:
    Using the workspace monorepo breaks the Android app's integration with @kesha-antonov/react-native-background-downloader. The monorepo's package hoisting and workspace resolution interferes with the native module's ability to properly register and resolve its native components. This causes runtime failures when attempting to download AI models in the background, which is a critical feature for this LLM chat example.

  2. Dependency Isolation: Bare React Native projects have distinct native dependency chains (iOS Pods, Android Gradle) that conflict with the monorepo's package management. The monorepo uses workspaces and hoisting strategies optimized for JavaScript/TypeScript packages, which can interfere with native module resolution.

@rizalibnu rizalibnu force-pushed the examples/bare-react-native branch from c27a355 to bb65951 Compare January 28, 2026 03:10
@msluszniak msluszniak force-pushed the feat/resource-fetcher-adapters branch from 6a63f5a to 246348c Compare February 17, 2026 16:31
msluszniak and others added 18 commits February 18, 2026 10:59
…oftware-mansion#811)

## Description

A base64 data URI (e.g. data:image/png;base64,iVBOR...) splits text into
2 segments, but the check was comparing against 1, causing all valid
base64 image inputs to be rejected.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [x] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [x] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [ ] Android

### Testing instructions

Run tests and check if they work.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

software-mansion#809 

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->

---------

Co-authored-by: ionkorol <ion@korol.dev>
…Native (software-mansion#759)

## Description

This PR introduces modular resource fetcher adapters to support both
Expo and bare React Native environments, replacing the previous
monolithic approach with a flexible, platform-specific architecture.

**Key Changes**
New Adapter Packages:

- @rn-executorch/expo-adapter: Resource fetcher for Expo projects using
expo-file-system and expo-asset
- @rn-executorch/bare-adapter: Resource fetcher for bare React Native
projects using @dr.pogodin/react-native-fs and
@kesha-antonov/react-native-background-downloader

**Initialization Changes:**

- Added initExecutorch() function that requires explicit adapter
selection
- Users must now choose and configure the appropriate adapter for their
project type
- Provides better separation of concerns and platform-specific
optimizations

**Documentation Updates:**
- Created individual README.md files for each adapter package

### Introduces a breaking change?

- [x] Yes
- [ ] No

**Migration Required:**
Users must now explicitly initialize the library with a resource fetcher
adapter:

```typescript
// Before (no initialization needed)
import { useLLM } from 'react-native-executorch';

// After (required initialization)
import { initExecutorch, useLLM } from 'react-native-executorch';
import { ExpoResourceFetcher } from '@rn-executorch/expo-adapter'; // or BareResourceFetcher

initExecutorch({
  resourceFetcher: ExpoResourceFetcher,
});
```

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [x] New feature (change which adds functionality)
- [x] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

**For Expo projects:**

- Install dependencies: `yarn add @rn-executorch/expo-adapter
expo-file-system expo-asset`
- Initialize: `initExecutorch({ resourceFetcher: ExpoResourceFetcher })`
- Run existing LLM example app to verify model downloads work correctly

**For bare React Native projects:**

- Install dependencies: `yarn add @rn-executorch/bare-adapter
@dr.pogodin/react-native-fs
@kesha-antonov/react-native-background-downloader`
- Initialize: `initExecutorch({ resourceFetcher: BareResourceFetcher })`
- Run the bare React Native example app in PR software-mansion#763

> Note: A separate PR will add a dedicated bare React Native example app
to make this PR easier to review. The Expo example apps can be used to
verify the Expo adapter functionality.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

Closes software-mansion#549 

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

**Why This Change:**

- Different React Native environments have different filesystem APIs and
c
- apabilities
- Expo projects benefit from using Expo's managed filesystem APIs
- Bare React Native projects can leverage native libraries with
background download support
- Modular architecture allows for better platform-specific optimizations
- Enables future extensibility for other environments (e.g., React
Native Windows, macOS)

**Split Into Multiple PRs:**
To make review easier, this work has been split:

- This PR: Core adapter infrastructure and Expo adapter implementation
- Follow-up PR: Bare React Native example app demonstrating the bare
adapter usage

BREAKING CHANGE: `initExecutorch()` with explicit adapter selection is
now required before using any react-native-executorch hooks. Users must
install and configure either `@rn-executorch/expo-adapter` or
`@rn-executorch/bare-adapter` depending on their project type.

---------

Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com>
Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com>
Co-authored-by: Jakub Chmura <92989966+chmjkb@users.noreply.github.com>
## Description

Adds GTM integration. Tag G-TJND8QJM9P is now embedded inside
GTM-WNBF6SVN container.
…nsion#814)

## Description

Refactors image segmentation into a generic, multi-model architecture.
Previously the module was hardcoded to DeepLab V3 — now it supports
multiple built-in models (DeepLab V3, selfie segmentation, RF-DETR) and
custom user-provided models with type-safe label maps.

**Key changes:**

- **C++ base class**: Extracted `BaseImageSegmentation` with virtual
`preprocess()`/`postprocess()` methods. `ImageSegmentation` is now a
thin subclass. This allows future models to override preprocessing (e.g.
different normalization) or postprocessing without duplicating the
pipeline.
- **Optional normalization in C++**: `readImageToTensor` now accepts
optional `normMean`/`normStd` params, eliminating duplicated
normalization logic. **also, imo it would be a good idea to do such
factories for the entire API**
- **Generic TypeScript module**: `ImageSegmentationModule<T>` is generic
over model name or custom `LabelEnum`. Two static factories:
`fromModelName()` (built-in models with auto label resolution) and
`fromCustomConfig()` (custom models with user-provided labels).
- **Generic hook**: `useImageSegmentation` infers the model's label
types from the config — no explicit generic parameter needed.
`forward()` return type narrows based on `classesOfInterest` passed in.
- **Correct return types**: `forward()` now returns `Record<'ARGMAX',
Int32Array> & Record<K, Float32Array>` matching what the native side
actually produces (was incorrectly typed as `number[]`).
- **ARGMAX always returned**: Removed `'ARGMAX'` from
`classesOfInterest` — it's always in the output regardless, and the
return type reflects this.

### Introduces a breaking change?

- [x] Yes
- [ ] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [x] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [x] Android

### Testing instructions

1. Build and run the `computer-vision` demo app
2. Navigate to Image Segmentation screen
3. Pick an image and run segmentation — verify the ARGMAX overlay
renders correctly
4. Verify the hook API works as expected:
```ts
const { isReady, forward } = useImageSegmentation({
  model: { modelName: 'deeplab-v3', modelSource: DEEPLAB_V3_RESNET50 },
});

// Returns Record<'ARGMAX', Int32Array> — no generic needed
const result = await forward(imageUri);

// Narrows return type to include 'PERSON' key as Float32Array
const result2 = await forward(imageUri, ['PERSON']);
```
5. Verify TypeScript autocompletion: `classesOfInterest` should only
suggest valid label keys for the chosen model (e.g. `'PERSON'`, `'CAR'`
for DeepLab, `'SELFIE'`/`'BACKGROUND'` for selfie segmentation)
6. You can also try changing the parameters, to say selfie segmentation
and see how the return types react. Please contact me for weights for
selfie segmentation as I'm not pushing them to HF yet

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

The `ImageSegmentationModule.fromCustomConfig()` API allows users to
bring their own segmentation model with a custom label map:
```ts
const MyLabels = { BACKGROUND: 0, FOREGROUND: 1 } as const;
const seg = await ImageSegmentationModule.fromCustomConfig(
  'https://example.com/model.pte',
  { labelMap: MyLabels },
);
```

---------

Co-authored-by: Mateusz Kopcinski <120639731+mkopcins@users.noreply.github.com>
## Description

This PR adds new tokenizer headers and bumps executorch binaries to
reflect the changes.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

Run apps for LLM, T2I, S2T, Embedding
## Description

This PR fixes few bugs related to the LLMs, caused by mixing two
approaches - functional (as we pass whole messages history each time)
and stateful (as we keep `pos_` in the runner, representing at which
position the KV cache is), which resulted in 3 bugs:

- broken KV cache for reasoning models - in the runner, we counted
tokens generated for the reasoning and included these in KV cache (`pos_
+= num_generated_tokens`), but in next turns, `jinja template` removed
these reasoning tokens from the messages history - as a result, KV-cache
was incoherent
- duplicated tokens in KV cache - we were passing whole messages history
to the runner (functional approach), but we were also appending all
tokens (prompt and generated) to the KV cache (which position is
represented by `pos_`) - as a result tokens were "duplicated" in the KV
cache and we were running out of available tokens very fast (exceeding
`context_window_length`)
- stateful TS functional API - even though our `generate()` method is
called functional, it kept internal state in the runner (e. g. `pos_`)

These bugs were fixed by resetting the runner before each generation,
which makes it truly functional - old messages are prefilled and the KV
cache can be still used during generation phase.

Additionally, this PR adds `ContextStrategy` to `ChatConfig` interface,
so now it's possible to define (or use one of already implemented)
strategy for managing context (e. g. naive, message count based, sliding
window) - it gives us more flexibility and user can decide what's best
for their use case. From now on, `SlidingWindowContextStrategy` is also
configured as the default one.

### Introduces a breaking change?

- [x] Yes
- [ ] No

These changes will not break anything until max number of messages is
not modified (I removed `contextWindowLength` from `ChatConfig` and
replaced it with `contextStrategy`)

### Type of change

- [x] Bug fix (change which fixes an issue)
- [x] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

Run example llm app, open executorch logs (`adb logcat | grep -i
"executorch"` for example) and see if numbers of tokens are properly
aligned and if `pos_` is correct.

To test different context management strategies, change
`contextStrategy` in llm app and modify model configuration.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

software-mansion#776

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

Position in KV cache, number of prompt tokens and number of generated
tokens for both non-reasoning and reasoning models BEFORE changes.

LLAMA 3.2 1B SPINQUANT (without reasoning)

| pos_             | Prompt tokens | Generated tokens |
|------------------|---------------|------------------|
| 0                | 335           | 269              |
| 604=269+335      | 872           | 372              |
| 1848=604+872+372 | 1513          | CRASH            |

QWEN 3.0 0.6B QUANTIZED (with reasoning)
| pos_             | Prompt tokens | Generated tokens |
|------------------|---------------|------------------|
| 0                | 309           | 457              |
| 766=309+457      | 617 (<766!)   | 192              |
| 1575=766+617+192 | 925 (<1575!)  | CRASH            |
## Description

This PR necessary scripts and CI workflows to handle autogenerated
API-reference docs. Currently, any change to the Typescript API changes
all references files because SHA in urls changes - as a result PRs are
hard to review and some bugs/discrepancies in docs can be merged more
easily.

This PR:
- adds CI workflow that checks if TS API-reference is up-to-date with
TypeDocs from code
- configures TypeDoc so urls point to `main` branch instead of specific
SHAs and so external references are excluded
- adds script for building versioned docs that build specific version of
docs and replaces all `main` occurences in reference URLs to appropriate
SHAs (we want to truncate the history there and point to specific point
in history instead of `main` branch)
- rebuilds docs with new configuration

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [x] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

N/A

### Testing instructions

**1. Script for building specific version of docs**

Run:

```bash
cd docs
yarn docs:version 0.8.x 
```

and verify if `main` was changed to valid SHA in all reference urls (so
urls for specific version are truncated to some point in history instead
of latest main)

**2. Github Action for detecting outdated api reference**

Check results of actions for commits
[7133ca4](software-mansion@7133ca4)
and
[2a4247c](software-mansion@2a4247c):
- the first commit introduces some changes to typescript api, but docs
were not built on purpose - as a result `Check if API reference is
up-to-date` workflow failed
- the first commit reverts this change, so generated api reference is
up-to-date with typedocs - as a result `Check if API reference is
up-to-date` workflow succeeded

**3. Start docs locally and check if everything (exceptionally
API-reference) works**

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

software-mansion#790

### Checklist

- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
## Description

This PR fixes paths on which `api-reference-up-to-date-check.yml`
workflow is triggered, so now any change to TS api triggers workflow
that checks if TS api reference is up-to-date

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

<!-- Provide step-by-step instructions on how to test your changes.
Include setup details if necessary. -->

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
…on#836)

## Description

<!-- Provide a concise and descriptive summary of the changes
implemented in this PR. -->

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

After merge it should trigger aggregated PR with all packages updated to
fixed versions.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
…xample app) (software-mansion#834)

## Description

This PR fixes permissions management for tool calling example app, so
user will be always prompted for missing permissions even if denied them
at some point. This PR:
- adds `Alert` that asks for permissions again
- adds banners (with links) that show missing permissions

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [x] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

Run LLM Tool Calling example app

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

software-mansion#774 

### Checklist

- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
## Description

Adds support for fm-2.5 instruct model.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

Run llm example app with model changed from `LLAMA3_2_1B_SPINQUANT` to
both `LFM2_5_1_2B_INSTRUCT` and `LFM2_5_1_2B_INSTRUCT_QUANTIZED`. Also
check that Hugging Face page for the model is correct and contains every
needed information:
https://huggingface.co/software-mansion/react-native-executorch-lfm2.5-1.2B-instruct.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

Closes software-mansion#812 

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
…ansion#838-software-mansion#877) (software-mansion#878)

Aggregates 40 Dependabot PRs into a single update:
- @evilmartians/lefthook: 1.13.6 -> 2.1.1
- @babel/core: 7.28.5 -> 7.29.0 (all apps)
- react: 19.1.0 -> 19.2.4 (packages + apps)
- react-native: 0.81.5 -> 0.84.0 (packages + apps/llm)
- react-native-svg: 15.12.1 -> 15.15.3 (all apps)
- react-native-svg-transformer: 1.5.2 -> 1.5.3 (all apps)
- react-native-screens: 4.16.0 -> 4.24.0 (llm, text-embeddings)
- react-native-safe-area-context: 5.6.2 -> 5.7.0 (speech,
text-embeddings)
- react-native-device-info: 14.1.1 -> 15.0.2 (all apps)
- react-native-reanimated: 4.1.6 -> 4.2.2 (computer-vision)
- react-native-worklets: 0.5.1 -> 0.7.4 (llm)
- react-native-audio-api: 0.11.3 -> 0.11.5 (speech)
- react-native-gesture-handler: 2.28.0 -> 2.30.0 (text-embeddings)
- @react-native/metro-config: 0.81.6 -> 0.84.0 (llm, speech)
- @react-navigation/drawer: 7.7.8 -> 7.8.1 (computer-vision, llm,
text-embeddings)
- @shopify/react-native-skia: 2.2.12 -> 2.4.21 (computer-vision)
- jest: 29.7.0 -> 30.2.0 (react-native-executorch)
- @types/jest: 29.5.14 -> 30.0.0 (react-native-executorch)
- zod: 3.25.76 -> 4.3.6 (react-native-executorch)
- expo-asset: 12.0.11 -> 12.0.12 (expo-resource-fetcher)
- @docsearch/css + sidepanel: 4.5.3 -> 4.6.0 (docs)
- typedoc: 0.28.16 -> 0.28.17 (docs)
- typedoc-plugin-markdown: 4.9.0 -> 4.10.0 (docs)
- swiper: 11.2.10 -> 12.1.2 (docs)

## Description

<!-- Provide a concise and descriptive summary of the changes
implemented in this PR. -->

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

* Run in `docs` directory `yarn build && yarn serve` and check that
documentation builds correctly
* Run all demo apps on iOS and Android and check that they are still
running correctly.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…-mansion#837)

## Description

This PR renames image segmentation, to more relevant and precise -
semantic segmentation

### Introduces a breaking change?

- [x] Yes
- [ ] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

Run tests, check Semantic Segmentation app in computer-vision/ 

Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com>
…, FCN (software-mansion#881)

## Description

Adds support for semantic segmentation models DeeplabV3, LRASPP, FCN,
both in quantized and FP32 versions.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

1. Run the computer vision semantic segmentation example app with all
added models.
2. Check HF pages for added models in the semantic segmentation
collection:
-
https://huggingface.co/software-mansion/react-native-executorch-deeplab-v3
- https://huggingface.co/software-mansion/react-native-executorch-lraspp
   - https://huggingface.co/software-mansion/react-native-executorch-fcn

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->
Closes software-mansion#799 software-mansion#830 

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->

---------

Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com>
## Description

This PR updates docs with full LLM configuration example.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [x] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

Check out docs and check out `useLLM` section (there are no examples for
`LLMModule` at all, so I did not add this there)

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [ ] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
…ware-mansion#886)

## Description

This PR fixes package.json in both expo and bare resource fetchers.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [x] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [ ] Android

### Testing instructions

* Run minimal app that utilizes this version of our library with expo 55
(pack react native executorch and expo resource fetchers into tgz and
install in template app) and check if everything works correctly.
* Run text to image example as this PR introduces changes in this
package and check if everything works ok.

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

Closes software-mansion#882 

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [ ] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
## Description

This PR adds real-time camera frame processing capabilities to React
Native ExecuTorch by integrating with VisionCamera v5. It introduces a
new VisionModule base class and extends ObjectDetectionModule to support
three input methods: image URLs/paths, raw pixel data (PixelData), and
live camera frames.

This PR includes:
- a dedicated screen for testing object detection + vision camera
- new tests for added methods

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [x] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [x] Android

### Testing instructions

Run the computer vision example app and test object detection and object
detection (live)

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [x] I have performed a self-review of my code
- [x] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

---------

Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com>
Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com>
…re-mansion#896)

## Description

Fix documentation about resource fetchers.

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [x] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

<!-- Provide step-by-step instructions on how to test your changes.
Include setup details if necessary. -->

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [ ] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
@msluszniak msluszniak force-pushed the examples/bare-react-native branch from bb65951 to 8816fbc Compare March 3, 2026 13:17
chmjkb and others added 5 commits March 3, 2026 15:31
…tware-mansion#826)

## Description

<!-- Provide a concise and descriptive summary of the changes
implemented in this PR. -->

### Introduces a breaking change?

- [x] Yes
- [ ] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [x] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [x] iOS
- [ ] Android

### Testing instructions

Run demo app with RF-DETR model

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [x] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [x] I have updated the documentation accordingly
- [x] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->

---------

Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com>
Co-authored-by: Mateusz Sluszniak <56299341+msluszniak@users.noreply.github.com>
Co-authored-by: Norbert Klockiewicz <Nklockiewicz12@gmail.com>
…sion#933)

Consolidate npm update configurations and change schedule to monthly.
Currently, every week there will be ~35 PR triggered by dependabot. This
change change frequency to only one per month, refactor config, do not
apply changes if there is only patch change.

## Description

<!-- Provide a concise and descriptive summary of the changes
implemented in this PR. -->

### Introduces a breaking change?

- [ ] Yes
- [x] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [x] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

<!-- Provide step-by-step instructions on how to test your changes.
Include setup details if necessary. -->

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [ ] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
## Description

<!-- Provide a concise and descriptive summary of the changes
implemented in this PR. -->

### Introduces a breaking change?

- [ ] Yes
- [ ] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

<!-- Provide step-by-step instructions on how to test your changes.
Include setup details if necessary. -->

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [ ] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
…ion#947)

## Summary

`TextToImage::unload()` is implemented in C++ and correctly delegates to
its sub-components (encoder, unet, decoder), but the JSI binding was
never registered in `ModelHostObject`. This causes a `TypeError:
this.nativeModule.unload is not a function` when calling
`BaseModule.delete()` from JavaScript.

Every other composite model (OCR, VerticalOCR, Kokoro, LLM) already
registers `unload` in its `if constexpr` block — this adds the same
one-liner for TextToImage.

## Changes

- Added `unload` JSI export to the `TextToImage` block in
`ModelHostObject.h`, matching the existing pattern used by other models

## Test plan

- [x] Call `module.delete()` on a loaded `TextToImageModule` — should no
longer throw
- [x] Verify model memory is released after `delete()` (encoder, unet,
decoder sub-models are unloaded)
Right now if you want to use Kokoro TTS, you have to go through the
built-in phonemis G2P pipeline. There's no way around it. This PR adds
`generateFromPhonemes` / `streamFromPhonemes` methods that let you skip
phonemis and pass your own IPA phoneme strings directly to the synthesis
engine.

Why would you want this? A few reasons we've run into:

- phonemis doesn't handle every word well. Libraries like
[phonemizer](https://github.com/bootphon/phonemizer) (espeak-ng backend)
do better on edge cases, foreign words, etc.
- Custom lexicons. If you have domain-specific pronunciation (game
character names, medical terms), you probably want control over the G2P
step.
- Server-side G2P. Pre-compute phonemes on a server with a proper NLP
pipeline, send them to the device.
- Languages phonemis doesn't cover yet.

## What changed

The existing `generate()` / `stream()` methods now delegate to shared
internal helpers (`generateFromPhonemesImpl` /
`streamFromPhonemesImpl`). The new public methods call the same helpers
but skip the `phonemizer_.process()` step. No behavior change for
existing callers.

Changes across layers:
- C++ `Kokoro`: `generateFromPhonemes`, `streamFromPhonemes` + input
validation (empty string, invalid UTF-8)
- JSI `ModelHostObject`: exposes new methods
- `TextToSpeechModule`: `forwardFromPhonemes()`, `streamFromPhonemes()`
(shared `streamImpl` helper, no copy-paste)
- `useTextToSpeech` hook: same, with shared guard + streaming
orchestration
- Types: `TextToSpeechPhonemeInput`,
`TextToSpeechStreamingPhonemeInput`, `TextToSpeechStreamingCallbacks`

## Usage

```typescript
const tts = new TextToSpeechModule();
await tts.load(config);

// text path (unchanged -- goes through phonemis)
const audio = await tts.forward("Hello world");

// phoneme path (bypasses phonemis)
const audio = await tts.forwardFromPhonemes("həloʊ wɝːld");

// streaming
for await (const chunk of tts.streamFromPhonemes({ phonemes: "həloʊ wɝːld", speed: 1.0 })) {
  playAudio(chunk);
}
```

## Test plan

- [ ] Existing `generate()` and `stream()` still work (refactor is
internal)
- [ ] `generateFromPhonemes()` with known Kokoro IPA strings
- [ ] `streamFromPhonemes()` produces same audio as `stream()` for
identical phonemes
- [ ] Multi-byte UTF-8 phoneme characters (ʊ, ɪ, ŋ, etc.)
- [ ] Empty string and invalid UTF-8 rejected with proper error

---------

Co-authored-by: IgorSwat <igorswat2002@o2.pl>
@msluszniak msluszniak force-pushed the examples/bare-react-native branch from b4e11d3 to 295701d Compare March 9, 2026 14:58
yocontra and others added 3 commits March 10, 2026 12:31
## Problem

The `loadModel` template in `RnExecutorchInstaller.h` constructs model
objects **synchronously on the JS thread**. For models like Kokoro TTS,
the constructor loads `.pte` files, initializes the phonemizer, and
reads voice data — blocking the JS thread for several seconds.

This prevents React from rendering any pending state updates (loading
spinners, progress indicators, etc.) until construction completes. For
example, calling `setIsSynthesizing(true)` followed by `tts.load()` will
not show the loading UI for 3-4 seconds because the JS thread is blocked
by the synchronous native constructor.

## Solution

Make `loadModel` return a **Promise** and dispatch the heavy model
construction to `GlobalThreadPool::detach` — matching the pattern
already used by `promiseHostFunction` for inference calls like
`generate()`.

### C++ (`RnExecutorchInstaller.h`)

- JSI arguments are still parsed on the JS thread (required for
`jsi::Value` access)
- Model construction is dispatched to `GlobalThreadPool::detach`
- The Promise resolves on the JS thread via `callInvoker->invokeAsync`
with the host object
- Error handling follows the same pattern as `promiseHostFunction` in
`ModelHostObject.h`

### TypeScript

- All `global.load*()` call sites updated to `await` the now-async
result
- Global type declarations updated to return `Promise<any>`
- `SpeechToText` already used `await`, so no change needed there

## Breaking Change

This is a breaking change for any consumers calling `global.load*()`
directly and expecting a synchronous return value. However:

- The public module APIs (`load()` methods) are already `async` — no
user-facing API changes needed
- The `global.load*()` functions are internal/undocumented

## Test Plan

- Verify model loading still works for all model types (TTS, LLM, OCR,
etc.)
- Verify that React state updates (loading spinners) render immediately
when `load()` is called, rather than being delayed until construction
completes
- Verify error handling still propagates correctly from native
construction failures

---------

Co-authored-by: Mateusz Słuszniak <mateusz.sluszniak@swmansion.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ty fixes (software-mansion#943)

Fixes for Kokoro TTS native code. Addresses voice data truncation,
missing Synthesizer method selection, progressive speed-up on longer
inputs, phoneme token reordering, and several additional safety fixes.

### Voice loading reads only 128 of 510 rows

`voice_` was a fixed `std::array<..., kMaxInputTokens>` (128 elements),
but `hexgrad/Kokoro-82M` voice files contain 510 rows. The remaining 382
rows were silently dropped.

Changed `voice_` to `std::vector`, sized dynamically from the file. Also
fixed an OOB in `voiceID` — upstream used `std::min(phonemes.size() - 1,
noTokens)` where `noTokens` could equal 128, indexing past the end of a
128-element array. Now uses a three-way `std::min({phonemes.size() - 1,
noTokens - 1, voice_.size() - 1})`.

### Synthesizer doesn't do method selection

`DurationPredictor` discovers and selects from
`forward_8`/`forward_32`/`forward_64`/`forward_128` based on input size,
but `Synthesizer` only knew about `forward`. Added the same discovery
and selection logic. Falls back to `"forward"` if no `forward_N` methods
exist, so older models still work.

### Audio progressively speeds up on longer inputs

The Synthesizer's attention mechanism drifts on longer input sequences
(60+ tokens), causing later phonemes to be spoken progressively faster
than the Duration Predictor intended. The DP's timing predictions are
correct, but the Synthesizer compresses later phonemes into fewer
samples.

Fixed by capping `inputTokensLimit` to 60, which forces the Partitioner
to split text into shorter chunks that the Synthesizer can render
faithfully. Each chunk is roughly one sentence (~15-20 words).

### `tokenize()` scrambles phoneme order on invalid tokens

`std::partition` was used to filter out invalid (unrecognized) phoneme
tokens, but `partition` does not preserve relative order. When any
phonemes fall outside the vocabulary, the remaining valid tokens could
be reordered, producing garbled audio.

Changed to `std::stable_partition` which preserves relative order.

### `stripAudio` unsigned integer underflow

`lbound - margin` wraps `size_t` to ~2^64 when the audio's first
non-silent sample is near the start of the buffer (i.e., `lbound <
margin`). `std::max(huge_value, 0)` returns the huge value, and
`audio.subspan()` reads out-of-bounds. This is especially triggered in
streaming mode where `paddingMs=15` (margin = 360 samples) on short
chunks.

Fixed by guarding the subtraction: `lbound > margin ? lbound - margin :
0`. Also guarded `audio.size() - 1` against empty spans.

### `isStreaming_` data race

`isStreaming_` is a plain `bool` read by `stream()` on a background
thread and written by `streamStop()` from the JS thread. Non-atomic
access is undefined behavior — the compiler may optimize away the read,
making `streamStop()` ineffective.

Changed to `std::atomic<bool>`.

### `scaleDurations` drops phonemes

When aggressively shrinking durations (many tokens, few total ticks),
individual token durations can be driven to 0 by the correction loop. A
zero-duration token is skipped by `repeatInterleave`, effectively
deleting that phoneme from the output.

Fixed by clamping each scaled duration to a minimum of 1, and guarding
the correction loop so it never drives a duration below 1. Without the
correction loop guard, the clamp is immediately undone — the priority
queue picks clamped entries (they have high remainders) and subtracts 1,
defeating the purpose.

### Misc perf

- Replace temporary pause zero-vectors with `resize()` directly on the
output
- Move-capture audio in the streaming callback instead of copying

## Changes

- `Kokoro.h` — `voice_` from fixed array to vector, `isStreaming_` to
`std::atomic<bool>`
- `Kokoro.cpp` — `loadVoice()`, `synthesize()`, `generate()`,
`stream()`, constructor token limit cap
- `DurationPredictor.cpp` — `scaleDurations()` min-1 clamp with
correction loop guard
- `Synthesizer.h` — `forwardMethods_` member
- `Synthesizer.cpp` — method discovery and selection
- `Utils.cpp` — `stable_partition` in `tokenize()`, `stripAudio`
underflow guard
## Description

The generated API reference under docs/docs/06-api-reference/ is
regenerated at build time by docusaurus-plugin-typedoc (runs as part of
yarn build), so there's no reason to track it in git. This removes the
files, gitignores the directory, and deletes the now-redundant
api-reference-up-to-date-check CI workflow.

### Introduces a breaking change?

- [ ] Yes
- [ ] No

### Type of change

- [ ] Bug fix (change which fixes an issue)
- [ ] New feature (change which adds functionality)
- [ ] Documentation update (improves or adds clarity to existing
documentation)
- [ ] Other (chores, tests, code style improvements etc.)

### Tested on

- [ ] iOS
- [ ] Android

### Testing instructions

<!-- Provide step-by-step instructions on how to test your changes.
Include setup details if necessary. -->

### Screenshots

<!-- Add screenshots here, if applicable -->

### Related issues

<!-- Link related issues here using #issue-number -->

### Checklist

- [ ] I have performed a self-review of my code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have updated the documentation accordingly
- [ ] My changes generate no new warnings

### Additional notes

<!-- Include any additional information, assumptions, or context that
reviewers might need to understand this PR. -->
rizalibnu and others added 17 commits March 10, 2026 17:54
…nerated files

- Resolve merge conflict in .github/workflows/ci.yml (keep topological prepare)
- Resolve merge conflict in yarn.lock and fix stale checksums
- Resolve merge conflict in ResourceFetcher.ts
- Update bare_rn: rename @rn-executorch/bare-adapter to @react-native-executorch/bare-resource-fetcher
- Switch bare_rn dependencies from file: to workspace: protocol
- Remove apps/bare_rn/android, ios, and yarn.lock from git index (covered by .gitignore)
- Remove integration test model assets from git index; add .gitignore to prevent re-tracking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cies

The jest@npm:^29.6.3 lockfile entry was corrupted during merge conflict
resolution, pointing to @jest/core@30.2.0 instead of @jest/core@29.7.0.
This caused Yarn hardened mode in CI to detect a resolution mismatch and
fail with YN0028.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Another corrupted lockfile entry from the merge conflict: metro-config@0.81.5
was referencing @react-native/babel-preset@0.84.0 instead of 0.81.5 deps,
causing the missing @react-native/metro-babel-transformer@0.81.5 in hardened
mode CI resolution.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pace

The lockfile had numerous corrupted entries from the merge conflict resolution
(wrong dep version ranges, mismatched babel/jest versions). Reset to origin/main
and ran yarn install to produce a clean lockfile that passes hardened mode.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ondition

The typecheck script was changed to run `react-native-executorch prepare`
before typechecking, but this causes a race condition in CI: the parallel
`yarn typecheck` step triggers bob build (which cleans lib/typescript) while
expo-resource-fetcher is concurrently typechecking against it, resulting in
TS2307 "Cannot find module 'react-native-executorch'" errors.

Revert to simple `tsc --noEmit` matching the main branch; CI already runs
`--topological-dev run prepare` before typecheck.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Unlike Expo apps, bare React Native requires native project directories
to build. Re-add ios/ and android/ for apps/bare_rn and update .gitignore
negation rules to allow them. Rename Android package from com.bare_rn to
com.barern to comply with Kotlin package naming conventions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ruby 3.4 removed kconv from its standard library. CocoaPods 1.15.x uses it
via CFPropertyList, causing pod install to fail. Adding the kconv gem
alongside the other Ruby 3.4 compat gems already in the Gemfile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CFPropertyList < 3.0.9 requires kconv which was removed from Ruby 3.4
standard library (there is no kconv gem). Pinning to 3.0.9+ uses a version
that no longer depends on kconv.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CocoaPods 1.16.0+ dropped the kconv dependency (removed from Ruby 3.4 stdlib).
Remove the xcodeproj < 1.26.0 upper bound since CocoaPods 1.16.x requires
xcodeproj >= 1.26.0. Also drop the now-unnecessary CFPropertyList pin.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
node_modules are hoisted to the repo root, so update settings.gradle
and app/build.gradle to point to ../../../node_modules/ instead of
../node_modules/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tasksMap bug

The @kesha-antonov/react-native-background-downloader library on Android
loses the task reference in its JS-side tasksMap, causing the done callback
to never fire even after a successful download. Fall back to RNFS.downloadFile
on Android which reliably resolves the promise on completion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@msluszniak msluszniak force-pushed the examples/bare-react-native branch from 9f75c02 to fe18a04 Compare March 10, 2026 16:54
msluszniak and others added 12 commits March 11, 2026 19:07
Keep rocket emoji in the description and 1️⃣/2️⃣/3️⃣ in the
quickstart section. Also remove bold from quickstart headings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Align ES, FR, CN, IN, PT readmes with the English README layout:
remove emoji prefixes from headings and table of contents, keep
:one:/:two:/:three: in quickstart steps, remove bold from step titles.

Also add --no-must-find-files to cspell hook so it doesn't fail when
all staged .md files are excluded by ignorePaths.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants