Skip to content

feat(resource-fetcher): add /auto side-effect entry points#1092

Open
msluszniak wants to merge 3 commits intomainfrom
feat/auto-init-resource-fetcher
Open

feat(resource-fetcher): add /auto side-effect entry points#1092
msluszniak wants to merge 3 commits intomainfrom
feat/auto-init-resource-fetcher

Conversation

@msluszniak
Copy link
Copy Markdown
Member

@msluszniak msluszniak commented Apr 23, 2026

Description

Forgetting initExecutorch({ resourceFetcher: ExpoResourceFetcher }) (or its BareResourceFetcher counterpart) before the first model call is a runtime footgun every Expo / bare consumer has to remember. The error message we throw is good — it directs users to the right packages — but the boilerplate itself shouldn't be needed.

This PR adds an opt-in side-effect entry point in each adapter package:

// at the top of App.tsx / app/_layout.tsx — once
import 'react-native-executorch-expo-resource-fetcher/auto';

// or, for bare React Native:
import 'react-native-executorch-bare-resource-fetcher/auto';

The new entries live in the adapter packages (rather than in react-native-executorch itself) so the main package doesn't need a hard dependency on either adapter implementation — bare-RN consumers don't get Expo bloat and vice versa.

Introduces a breaking change?

  • Yes
  • No

Strictly additive. The manual initExecutorch({ resourceFetcher: ... }) API stays exactly as is — same module export, same signature. Existing consumers are unaffected. Use the manual API when you need to register a different adapter, swap adapters at runtime, or order the registration relative to other side effects; use the new /auto entry when you have nothing custom to configure.

Type of change

  • Bug fix
  • New feature (change which adds functionality)
  • Documentation update
  • Other

Tested on

  • iOS
  • Android

Pure JS plumbing — no native code touched. Verified locally that:

  • yarn workspace ... run prepare produces lib/auto.{js,d.ts} artifacts in both adapter packages.
  • yarn typecheck passes across all workspaces.
  • eslint and prettier --check pass on the new files.

Testing instructions

In any RNE consumer:

  • 1. Replace the existing initExecutorch({ resourceFetcher: ExpoResourceFetcher }) call with a single side-effect import at app entry: import 'react-native-executorch-expo-resource-fetcher/auto';.
  • 2. Boot the app and load any model. The ResourceFetcher adapter is not initialized error should not surface (which it would have if you'd just deleted the initExecutorch call without the new import).
  • 3. Optionally verify the manual initExecutorch(...) flow still works by running an app that uses it — output should be identical.

Related issues

Addresses item 5 of #1086.

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

  • A reasonable follow-up (out of scope for this PR) is a docs update that recommends the /auto entry as the default for new projects.
  • Naming: I went with /auto for brevity (consistent with the expo-router/entry reference pointed at in the issue). Open to alternatives like /register or /init if you prefer.

Adds opt-in side-effect imports for both adapter packages that call
`initExecutorch({ resourceFetcher: ... })` for the user:

  import 'react-native-executorch-expo-resource-fetcher/auto';
  // or
  import 'react-native-executorch-bare-resource-fetcher/auto';

Use it once at app entry instead of the boilerplate manual
`initExecutorch({ resourceFetcher: ExpoResourceFetcher })` call. The
manual API stays — use it when you need to register a different
adapter, swap adapters at runtime, or order the registration relative
to other side effects.

Strictly additive: existing consumers' `initExecutorch(...)` calls keep
working unchanged. The auto entries live in the adapter packages
(rather than in `react-native-executorch` itself) so the main package
doesn't need a hard dependency on either adapter implementation.

Refs #1086 (item 5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@msluszniak msluszniak marked this pull request as draft April 23, 2026 08:40
msluszniak and others added 2 commits April 23, 2026 10:48
Migrate the five demo apps (computer-vision, llm, text-embeddings,
speech, bare-rn) to the new `/auto` side-effect import added in the
previous commit. Each app drops its `initExecutorch({ resourceFetcher: ... })`
boilerplate and the corresponding `initExecutorch` / fetcher imports
in favor of:

  import 'react-native-executorch-expo-resource-fetcher/auto';
  // or, for bare-rn:
  import 'react-native-executorch-bare-resource-fetcher/auto';

Update the user-facing docs (`01-getting-started.md`,
`02-loading-models.md`) to lead with the `/auto` pattern and present
`initExecutorch(...)` as the "more control" alternative for custom
adapters or runtime swapping. Custom-adapter and API-reference docs
are unchanged — both legitimately use the manual API.

Also fixes a pre-existing wrong import path in `02-loading-models.md`:
the bare adapter was shown as `@react-native-executorch/bare-adapter`,
which does not exist; corrected to `react-native-executorch-bare-resource-fetcher`.

Refs #1086 (item 5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The "ResourceFetcher adapter is not initialized" error currently only
mentions the manual `initExecutorch({ resourceFetcher: ... })` path.
With the new `/auto` side-effect entry, there's a one-line fix that
the error should surface first. Update the message to lead with the
auto entry and keep `initExecutorch(...)` as the "for full control"
fallback.

Refs #1086 (item 5).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@msluszniak msluszniak self-assigned this Apr 23, 2026
@msluszniak msluszniak added the feature PRs that implement a new feature label Apr 23, 2026
@msluszniak msluszniak marked this pull request as ready for review April 23, 2026 09:00
@chmjkb
Copy link
Copy Markdown
Collaborator

chmjkb commented Apr 23, 2026

Does this actually solve the problem? You still have to read the docs and do a manual thing, which is importing a specific module, we're just being less explicit about it

@msluszniak
Copy link
Copy Markdown
Member Author

Maybe we should handle this as it is done in expo-router/entry for avoiding AppRegistry.registerComponent(...) written manually. I'm thinking how to make it more user friendly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature PRs that implement a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants