Skip to content

fix(ios): load thumbImage/trackImage without the legacy bridge on bridgeless (new arch)#821

Open
arron-kukadia wants to merge 1 commit into
callstack:mainfrom
arron-kukadia:fix/ios-thumbimage-bridgeless
Open

fix(ios): load thumbImage/trackImage without the legacy bridge on bridgeless (new arch)#821
arron-kukadia wants to merge 1 commit into
callstack:mainfrom
arron-kukadia:fix/ios-thumbimage-bridgeless

Conversation

@arron-kukadia

@arron-kukadia arron-kukadia commented Jul 17, 2026

Copy link
Copy Markdown

Summary

On bridgeless React Native (the default new-architecture mode since RN 0.74+), thumbImage, trackImage, minimumTrackImage and maximumTrackImage silently fail to render on iOS. loadImageFromImageSource resolves the ImageLoader through [RCTBridge currentBridge] (flagged by the existing TODO in the file), which doesn't reliably provide a working ImageLoader without the legacy bridge — the completion never delivers an image, and the slider falls back to the default thumb.

Fixes #773

Fix

Keep the existing ImageLoader path as the first attempt (no behaviour change where it works). If the module is unavailable or returns no image, fall back to fetching the image directly with NSURLSession using the same NSURLRequest — this covers bundled file:// assets, Metro URLs in dev, and remote images, and honours custom request headers. The retry-on-no-image (rather than only on missing module) is deliberate: on bridgeless, the interop layer can hand back an ImageLoader instance that exists but cannot load, so gating on module presence alone would not fix the bug.

Details:

  • The NSURLSession completion invokes the callbacks on the main queue, since failureBlock call sites in updateProps mutate UIKit directly and previously only ran synchronously on the main thread.
  • The scale fallback uses RCTScreenScale() (not [UIScreen mainScreen], which is unavailable on visionOS — this pod declares visionOS support).
  • The stale TODO comment is replaced with one describing the current dual-path behaviour.

Known limitations of the fallback

These apply only on bridgeless, where the fallback is effectively the primary path, and match the documented thumbImage API surface (static local/network images):

  • RCTImageURLLoader plugin schemes (e.g. ph://, custom app-registered schemes) are not supported by NSURLSession and will fail; they were undocumented for this component but worked via the bridge ImageLoader on the old architecture.
  • The fallback does not apply ImageLoader's decode-time resizing (source.size + cover mode) or decoded-image caching. A remote {uri, width, height} source without thumbSize decodes and renders at intrinsic bitmap size.

Both could be addressed by resolving RCTImageLoader from the new-arch module registry (or ultimately the Fabric ImageManager pipeline) — left out of scope here to keep this a minimal fix for #773.

Test plan

Verified in a production Expo SDK 56 / RN 0.85 app (bridgeless, new arch): before the change thumbImage renders the default circle; after it, the custom thumb renders correctly in both dev (Metro-served asset) and release (bundled asset). Android untouched.

@arron-kukadia
arron-kukadia force-pushed the fix/ios-thumbimage-bridgeless branch from a6c01c2 to 0f4c906 Compare July 17, 2026 15:04
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.

thumbImage not working on Rn 0.84.0

1 participant