sootsim 0.1.62 → 0.1.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist-cli/bin.js +3 -3
  2. package/dist-cli/chunks/{agent-VKARDTF5.js → agent-SHMN3LWB.js} +2 -2
  3. package/dist-cli/chunks/{agent-wrapper-6QDQ77TJ.js → agent-wrapper-ESDQSMYX.js} +2 -2
  4. package/dist-cli/chunks/{assert-PYSEWHJK.js → assert-X3GQJUDI.js} +2 -2
  5. package/dist-cli/chunks/auto-bootstrap-PH4II3F2.js +2 -0
  6. package/dist-cli/chunks/beta-YKR6YRXH.js +2 -0
  7. package/dist-cli/chunks/{chunk-35UHLN73.js → chunk-2GAZ3JW7.js} +2 -2
  8. package/dist-cli/chunks/{chunk-4JXE3ZUG.js → chunk-346HJVD6.js} +1 -1
  9. package/dist-cli/chunks/{chunk-3VE2XCQM.js → chunk-34PKFCEI.js} +3 -3
  10. package/dist-cli/chunks/{chunk-5POON745.js → chunk-3R3BQDKC.js} +2 -2
  11. package/dist-cli/chunks/{chunk-H2QWYBE2.js → chunk-6X3I2LF4.js} +2 -2
  12. package/dist-cli/chunks/{chunk-WN2ATVFO.js → chunk-ALDKVFW3.js} +2 -2
  13. package/dist-cli/chunks/{chunk-TALVQX2P.js → chunk-BT6IVKHN.js} +1 -1
  14. package/dist-cli/chunks/chunk-CETSCOUK.js +1 -0
  15. package/dist-cli/chunks/{chunk-6TJONB3X.js → chunk-DJIQVKM6.js} +10 -10
  16. package/dist-cli/chunks/{chunk-3N6CKIJG.js → chunk-DSLBZC6J.js} +2 -2
  17. package/dist-cli/chunks/{chunk-DV4MSLJL.js → chunk-E5EWHEA5.js} +2 -2
  18. package/dist-cli/chunks/{chunk-63NGN7QH.js → chunk-FFVJK2R7.js} +2 -2
  19. package/dist-cli/chunks/{chunk-RIYRSTXD.js → chunk-G4GM43A7.js} +2 -2
  20. package/dist-cli/chunks/{chunk-ND2UZFA4.js → chunk-GKUKCZBA.js} +44 -44
  21. package/dist-cli/chunks/{chunk-CEOCVI4R.js → chunk-HERZHQFG.js} +2 -2
  22. package/dist-cli/chunks/{chunk-6XLG7CQG.js → chunk-J6TCNU6W.js} +1 -1
  23. package/dist-cli/chunks/chunk-KY2VMN66.js +1 -0
  24. package/dist-cli/chunks/{chunk-DN47N6UL.js → chunk-L3MRXOBW.js} +3 -3
  25. package/dist-cli/chunks/{chunk-EIXXQDAI.js → chunk-LKJI7RRW.js} +2 -2
  26. package/dist-cli/chunks/{chunk-DNAVJIEL.js → chunk-M4CADRP5.js} +2 -2
  27. package/dist-cli/chunks/{chunk-3BWDOYAV.js → chunk-N63QYSHT.js} +3 -3
  28. package/dist-cli/chunks/{chunk-V3TU7DR4.js → chunk-OBL6OIK5.js} +1 -1
  29. package/dist-cli/chunks/chunk-OBSMT5TS.js +2 -0
  30. package/dist-cli/chunks/{chunk-VBA6DIBD.js → chunk-PXRELDJJ.js} +2 -2
  31. package/dist-cli/chunks/{chunk-Q5EKBSA2.js → chunk-R6ZTREB6.js} +2 -2
  32. package/dist-cli/chunks/{chunk-NXFXTJSP.js → chunk-RKUDWRIN.js} +2 -2
  33. package/dist-cli/chunks/{chunk-UEF3ZIEI.js → chunk-RQHWF2OD.js} +2 -2
  34. package/dist-cli/chunks/{chunk-OMSSLTQC.js → chunk-RRGCQNVD.js} +1 -1
  35. package/dist-cli/chunks/{chunk-3WZ7ZTIA.js → chunk-SMYSG4VE.js} +1 -1
  36. package/dist-cli/chunks/{chunk-C6LE22VK.js → chunk-SVT7H2QF.js} +2 -2
  37. package/dist-cli/chunks/{chunk-6RJRJRAW.js → chunk-T5TDH2UO.js} +1 -1
  38. package/dist-cli/chunks/{chunk-J5RNZMJJ.js → chunk-UVDVALC7.js} +2 -2
  39. package/dist-cli/chunks/{chunk-66KS2T62.js → chunk-VE4QTDAY.js} +2 -2
  40. package/dist-cli/chunks/{chunk-2JSZSUTN.js → chunk-VGD57MTN.js} +2 -2
  41. package/dist-cli/chunks/{chunk-6EUVCG33.js → chunk-WKVIKFMU.js} +1 -1
  42. package/dist-cli/chunks/chunk-WN4XOOK5.js +2 -0
  43. package/dist-cli/chunks/{chunk-4MZLNYBR.js → chunk-X3QWOTLT.js} +1 -1
  44. package/dist-cli/chunks/chunk-XHD3XCT5.js +1 -0
  45. package/dist-cli/chunks/{chunk-JIEJ2O4W.js → chunk-XHDHG6YH.js} +1 -1
  46. package/dist-cli/chunks/{chunk-BIZ4APXE.js → chunk-YGMHOMAJ.js} +2 -2
  47. package/dist-cli/chunks/{chunk-YRKWTQ66.js → chunk-YJIQYIHM.js} +1 -1
  48. package/dist-cli/chunks/{chunk-TIUEUINU.js → chunk-YXZFG3ZY.js} +1 -1
  49. package/dist-cli/chunks/{chunk-YAKDXQA7.js → chunk-ZV2TI6OH.js} +2 -2
  50. package/dist-cli/chunks/cli-version-32VNOX3F.js +2 -0
  51. package/dist-cli/chunks/{compat-GO5ZKWUL.js → compat-SOHG4UE5.js} +3 -3
  52. package/dist-cli/chunks/{config-GWDGFFIB.js → config-JQF6TGCG.js} +2 -2
  53. package/dist-cli/chunks/control-GIAGLNPG.js +2 -0
  54. package/dist-cli/chunks/{cpu-profile-TQRN7NFF.js → cpu-profile-3C7LHLJE.js} +2 -2
  55. package/dist-cli/chunks/{daemon-XLTCNIET.js → daemon-SD773LNY.js} +2 -2
  56. package/dist-cli/chunks/{debug-324KIABR.js → debug-MNWVCAAF.js} +3 -3
  57. package/dist-cli/chunks/demo-app-registry-JUKLYD4R.js +2 -0
  58. package/dist-cli/chunks/{detox-QGITZG47.js → detox-VOWHHVNU.js} +2 -2
  59. package/dist-cli/chunks/{device-6WFYBS5R.js → device-TFKPS72A.js} +2 -2
  60. package/dist-cli/chunks/{diagnose-HBDMYEKJ.js → diagnose-J2BTJTGW.js} +2 -2
  61. package/dist-cli/chunks/drivers-HVKRY4MB.js +2 -0
  62. package/dist-cli/chunks/{electron-5DX3DITH.js → electron-NHJHQAOJ.js} +3 -3
  63. package/dist-cli/chunks/flow-D6MKC5NH.js +2 -0
  64. package/dist-cli/chunks/{hints-CJ3ETNUR.js → hints-XONGBPNI.js} +2 -2
  65. package/dist-cli/chunks/{home-paths-OCOWHSRV.js → home-paths-KK7NZVIK.js} +2 -2
  66. package/dist-cli/chunks/{inspect-QPZXN3IK.js → inspect-7AINMWI2.js} +135 -102
  67. package/dist-cli/chunks/install-YPSDICK4.js +2 -0
  68. package/dist-cli/chunks/{install-desktop-RB3JNYHC.js → install-desktop-CRFW4MDL.js} +3 -3
  69. package/dist-cli/chunks/{keys-HFOS3J5A.js → keys-PLJITE2X.js} +2 -2
  70. package/dist-cli/chunks/{launch-XQGAPI6Q.js → launch-FHMTFUI3.js} +3 -3
  71. package/dist-cli/chunks/{login-U6ZPN4IL.js → login-DCFVFSY3.js} +4 -4
  72. package/dist-cli/chunks/{logout-VY2F5T4J.js → logout-55UH67FS.js} +2 -2
  73. package/dist-cli/chunks/{maestro-32UN2FHS.js → maestro-HNNW73KG.js} +2 -2
  74. package/dist-cli/chunks/{preview-AJWIS25K.js → preview-EYIZWAEJ.js} +2 -2
  75. package/dist-cli/chunks/{profile-4XPDQIQY.js → profile-UOG2ET7W.js} +2 -2
  76. package/dist-cli/chunks/{react-VSZ2RQEC.js → react-MRICF5YD.js} +2 -2
  77. package/dist-cli/chunks/record-33ZECMTQ.js +50 -0
  78. package/dist-cli/chunks/runtime-OG4HGCYH.js +2 -0
  79. package/dist-cli/chunks/{runtime-delivery-O7G4Y6GE.js → runtime-delivery-KYEJ3C24.js} +2 -2
  80. package/dist-cli/chunks/{screenshot-ALDT4B77.js → screenshot-B6B3CE2W.js} +2 -2
  81. package/dist-cli/chunks/{screenshot-mode-5VYUB7G6.js → screenshot-mode-QVII6GH6.js} +2 -2
  82. package/dist-cli/chunks/{screenshots-TYQ4EVJR.js → screenshots-GYQ3JHAW.js} +2 -2
  83. package/dist-cli/chunks/{server-X2GDTWC6.js → server-G4WPXKFR.js} +2 -2
  84. package/dist-cli/chunks/setup-repo-2TQURG52.js +2 -0
  85. package/dist-cli/chunks/{skills-C6RSSO4R.js → skills-RF27H27Y.js} +2 -2
  86. package/dist-cli/chunks/{start-Y2S3LSL5.js → start-EBOUYGAP.js} +4 -4
  87. package/dist-cli/chunks/store-FRMH2SYG.js +2 -0
  88. package/dist-cli/chunks/telemetry-EZIRTFFL.js +2 -0
  89. package/dist-cli/chunks/{test-IAHTJWBS.js → test-SATSKLC6.js} +3 -3
  90. package/dist-cli/chunks/{three-mode-ZCZXY47S.js → three-mode-XLTSGRVJ.js} +2 -2
  91. package/dist-cli/chunks/{timeline-KZHGTPDV.js → timeline-ELOCAU3S.js} +2 -2
  92. package/dist-cli/chunks/{upgrade-47JCBCFB.js → upgrade-2OZLYETX.js} +2 -2
  93. package/dist-cli/chunks/upload-SJCUW6BT.js +2 -0
  94. package/dist-cli/chunks/web-YOKL7JUD.js +2 -0
  95. package/dist-cli/chunks/{what-happened-FULTHMRQ.js → what-happened-YGFJR2TI.js} +2 -2
  96. package/dist-cli/chunks/{whoami-3KUBLDUA.js → whoami-GKH3GF3H.js} +2 -2
  97. package/dist-lib/agent-daemon-client.cjs +1 -1
  98. package/dist-lib/agent-events.cjs +1 -1
  99. package/dist-lib/agent-sessions.cjs +1 -1
  100. package/dist-lib/attached-projects.cjs +1 -1
  101. package/dist-lib/auth/shared-session.cjs +1 -1
  102. package/dist-lib/backend-origin.cjs +1 -1
  103. package/dist-lib/bridge-constants.cjs +1 -1
  104. package/dist-lib/cli-constants.cjs +1 -1
  105. package/dist-lib/config.cjs +1 -1
  106. package/dist-lib/dev-bundle-resolution.cjs +1 -1
  107. package/dist-lib/home-paths.cjs +1 -1
  108. package/dist-lib/host/bridge-host.cjs +1 -1
  109. package/dist-lib/host/fetch-proxy-handler.cjs +1 -1
  110. package/dist-lib/host/fetch-proxy-overrides.cjs +1 -1
  111. package/dist-lib/index.cjs +1 -1
  112. package/dist-lib/metro.cjs +1 -1
  113. package/dist-lib/profiles.cjs +1 -1
  114. package/dist-lib/render-mode.cjs +1 -1
  115. package/dist-lib/vite-base.cjs +1 -1
  116. package/dist-lib/vite.cjs +1 -1
  117. package/package.json +1 -1
  118. package/dist-cli/chunks/auto-bootstrap-SUDPJ45T.js +0 -2
  119. package/dist-cli/chunks/beta-3HRWHUIR.js +0 -2
  120. package/dist-cli/chunks/chunk-DYYNEGJV.js +0 -2
  121. package/dist-cli/chunks/chunk-S2RNIQCY.js +0 -1
  122. package/dist-cli/chunks/chunk-T6IRZEOS.js +0 -1
  123. package/dist-cli/chunks/chunk-TSGJJFFO.js +0 -1
  124. package/dist-cli/chunks/chunk-XTR4CILB.js +0 -2
  125. package/dist-cli/chunks/cli-version-INI6PYTD.js +0 -2
  126. package/dist-cli/chunks/control-GMAG2HKS.js +0 -2
  127. package/dist-cli/chunks/demo-app-registry-OEAV2G5S.js +0 -2
  128. package/dist-cli/chunks/drivers-TJSMGOQQ.js +0 -2
  129. package/dist-cli/chunks/flow-HNHYMZO6.js +0 -2
  130. package/dist-cli/chunks/install-OVCWRSPD.js +0 -2
  131. package/dist-cli/chunks/record-W6ZTLQTB.js +0 -45
  132. package/dist-cli/chunks/runtime-6UMHX7N7.js +0 -2
  133. package/dist-cli/chunks/setup-repo-Q7SMPBCH.js +0 -2
  134. package/dist-cli/chunks/store-ABVWLB26.js +0 -2
  135. package/dist-cli/chunks/telemetry-2LWDURQ5.js +0 -2
  136. package/dist-cli/chunks/upload-PNZ3UEOL.js +0 -2
  137. package/dist-cli/chunks/web-N6G3E6EE.js +0 -2
@@ -0,0 +1,2 @@
1
+ /*! sootsim v0.1.64 | (c) 2026 Tamagui LLC | Proprietary — see LICENSE */
2
+ import"./chunk-J6TCNU6W.js";var v=["All","Essentials","Navigation","Animation","Image","Keyboard","Lists & Sheets","UI Components","Media","Maps","Storage & Data","Auth & Payments","Notifications","Networking","Device & Platform","Health","Calendar","ML","Expo SDK","Analytics","Internationalization"],g={"react-native-reanimated":{category:"Essentials",stubType:"native",versions:[{range:">=2.0.0 <3.0.0",coverage:.6,note:"basic shared values + timing"},{range:">=3.0.0 <4.0.0",coverage:.75,note:"scroll handlers, layout animations"},{range:">=4.0.0",coverage:.8,note:"shared values, timing/spring/decay, interpolate, scroll handlers, createAnimatedComponent, frame callbacks",working:"useSharedValue, useAnimatedStyle/Props/Reaction, useDerivedValue, useAnimatedScrollHandler, useFrameCallback, useAnimatedRef, withTiming/Spring/Decay/Delay/Sequence/Repeat/Clamp, interpolate, interpolateColor, runOnJS/UI, measure, scrollTo, Easing, createAnimatedComponent, Animated.View/Text/Image/ScrollView/FlatList",missing:"layout animation builders are exported but no enter/exit animation actually plays, useScrollViewOffset returns static 0, useAnimatedSensor static, useReducedMotion always false, useAnimatedKeyboard height tracking returns 0"}]},"react-native-gesture-handler":{category:"Essentials",stubType:"native",versions:[{range:">=2.0.0 <2.30.0",coverage:.7,note:"tap, pan, long press"},{range:">=2.30.0",coverage:.9,note:"tap, pan, pinch, rotation, fling, long press, race, manual, simultaneous",working:"GestureDetector, Gesture.Tap/Pan/Pinch/Rotation/Fling/LongPress/Manual/Race/Simultaneous/Exclusive/Hover, ScrollView/FlatList, Switch/RefreshControl, Pressable/Text, Touchables, BaseButton/RawButton/RectButton/BorderlessButton/PureNativeButton, Swipeable, ReanimatedSwipeable, GestureHandlerRootView, createNativeWrapper, gestureHandlerRootHOC, PointerType/MouseButton/HoverEffect exports, velocity tracking, activeOffsets, multi-tap",missing:"DrawerLayout (passthrough noop), NativeViewGestureHandler still lacks native-scroll coupling and handlerTag semantics, cross-detector simultaneousWithExternalGesture/requireExternalGestureToFail, ForceTouch semantics are placeholder-only"}]},"react-native-screens":{category:"Essentials",stubType:"native",versions:[{range:">=3.0.0 <4.0.0",coverage:.6,note:"basic screen container"},{range:">=4.0.0",coverage:.87,note:"screen container, stack, header config, search bar, navigation props",working:"Screen, ScreenContainer, ScreenStack, Android modal/pageSheet push fallback, Android statusBarHidden/statusBarStyle/navigationBarHidden traits, push/pop slide, zoom/fade/fade_from_bottom transitions, edge swipe-back, parallax behind-screen, large title collapse, header (back button, inline/large title, custom left/center/right/search bar subviews, crossfade), useHeaderHeight, useTransitionProgress, FullWindowOverlay, SearchBar, Tabs.Host/Screen, lifecycle callbacks (onAppear/onDisappear/onWillAppear/onWillDisappear), onDismissed",missing:"freezeEnabled/enableFreeze (always false), statusBarColor/navigationBarColor/navigationBarTranslucent ignored, replaceAnimation differentiation, formSheet detent fidelity, integrated search bar placements"}]},"react-native-safe-area-context":{category:"Essentials",stubType:"native",versions:[{range:">=4.0.0",coverage:.97,note:"live device/system-bar/ime metrics, edges/mode padding, hooks",working:"SafeAreaProvider with live Android system-bar and IME-resized frame metrics, SafeAreaView (edges/mode padding/margin), useSafeAreaInsets, useSafeAreaFrame, SafeAreaInsetsContext, SafeAreaFrameContext, initialWindowMetrics, SafeAreaListener onInsetsChange, withSafeAreaInsets HOC",missing:"rotation-specific provider frame deltas"}]},"react-native-svg":{category:"Image",stubType:"native",versions:[{range:">=13.0.0",coverage:.85,note:"full CanvasKit rendering for shapes/text/XML; SVG filter elements skipped",working:"Svg, Path, Circle, Rect, Line, Ellipse, Polygon, Polyline, G, Text, TSpan, Defs, ClipPath, LinearGradient, RadialGradient, Stop, Mask, Symbol, Use, Pattern, ForeignObject, Image, Marker, SvgXml, SvgUri, SvgFromXml, SvgCss, transforms, fill/stroke/opacity/dasharray, currentColor, viewBox scaling",missing:"SVG filter primitives (Filter, FeBlend, FeColorMatrix, FeGaussianBlur, FeComposite, etc) \u2014 all fe* skipped; ClipPath/Mask/Use/Pattern/Symbol/Image listed as skipped in engine"}]},"@react-native-async-storage/async-storage":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"full localStorage-backed implementation"}]},"react-native-webview":{category:"Essentials",stubType:"native",versions:[{range:">=11.0.0",coverage:.35,note:"DOM iframe path only; sootsim canvas path is a native-view bridge placeholder",working:"source.uri/source.html, injectedJavaScriptBeforeContentLoaded, injectedJavaScript, ReactNativeWebView.postMessage bridge, onMessage, onLoad/Start/End, onNavigationStateChange, onError, ref.goBack/goForward/reload/stopLoading/injectJavaScript/postMessage, renderLoading, renderError, javaScriptEnabled sandbox in DOM/web contexts",missing:"actual web content rendering inside the canvas worker, onShouldStartLoadWithRequest, allowsBackForwardNavigationGestures, userAgent, dataDetectorTypes, cacheEnabled, incognito, scalesPageToFit, canGoBack/Forward in iframe-mode (always false), originWhitelist enforcement"}]},"@expo/dom-webview":{category:"Essentials",stubType:"native",versions:[{range:">=55.0.0",coverage:.35,note:"thin re-export of react-native-webview \u2014 Expo DOM is conceptually the same surface (WebView component + postMessage/injectJavaScript) and so inherits its compat: real iframe-backed DOM rendering with the message bridge, navigation callbacks, and ref imperative API. Same caveats as react-native-webview (canvas-worker placeholder for the native-view path, no onShouldStartLoadWithRequest).",working:"DomWebView/WebView exports, source.uri/source.html, ReactNativeWebView.postMessage bridge, onMessage, onLoad/Start/End, onNavigationStateChange, onError, ref.goBack/goForward/reload/stopLoading/injectJavaScript/postMessage, renderLoading/renderError, javaScriptEnabled in DOM contexts",missing:"native DOM component registry beyond what react-native-webview already provides, exact scrollTo semantics, native-view canvas rendering, onShouldStartLoadWithRequest, allowsBackForwardNavigationGestures, originWhitelist enforcement"}]},"@shopify/flash-list":{category:"Lists & Sheets",stubType:"native",versions:[{range:">=1.0.0",coverage:.8,note:"FlashList and MasonryFlashList rendered as engine FlatList \u2014 core rendering works",working:"FlashList (renders as FlatList with full props passthrough), MasonryFlashList (alias to same), ref forwarding",missing:"native recycling/virtualization engine, estimatedItemSize perf tuning, overrideItemLayout, drawDistance, horizontal masonry layout, onBlankArea callback"}]},"@react-native-community/netinfo":{category:"Device & Platform",stubType:"native",versions:[{range:">=9.0.0",coverage:.95,note:"navigator.onLine backed with online/offline event listeners",working:"fetch, useNetInfo, addEventListener, NetInfoStateType",missing:'details field always null (no connection type subtype), type always "wifi" or "none" (no cellular/ethernet detection)'}]},"react-native-keyboard-controller":{category:"Keyboard",stubType:"native",versions:[{range:">=1.0.0",coverage:.88,note:"native bindings stubbed (KeyboardControllerNative, KeyboardEvents, FocusedInputEvents, WindowDimensionsEvents, KeyboardControllerView + sibling native views); upstream pure-JS components, hooks, animated module, and KeyboardAvoidingView resolve from node_modules unchanged",working:"every upstream JS export \u2014 KeyboardProvider, KeyboardAvoidingView, KeyboardStickyView, KeyboardAwareScrollView, KeyboardToolbar, KeyboardGestureArea, useReanimatedKeyboardAnimation, useKeyboardAnimation, useKeyboardHandler, useGenericKeyboardHandler, useKeyboardController, useKeyboardState, useKeyboardContext, useReanimatedFocusedInput, useFocusedInputHandler, useResizeMode, useWindowDimensions, KeyboardEvents, FocusedInputEvents, WindowDimensionsEvents resize events, KeyboardController (dismiss/setFocusTo/isVisible/state/preload/setInputMode/setDefaultMode), KeyboardControllerView, OverKeyboardView, KeyboardBackgroundView, KeyboardExtender, ClippingScrollView, KeyboardToolbarGroupView, AndroidSoftInputModes \u2014 all run upstream code through reanimated worklets",missing:"per-frame keyboard progress events (smooth `onMove` requires SAB-backed shared values driven from the shell-side keyboard animation; deferred \u2014 see plans/real-worklets.md)"}]},"@react-native-masked-view/masked-view":{category:"Essentials",stubType:"native",versions:[{range:">=0.2.0",coverage:1,note:"engine-level masked-view node with canvaskit saveLayer + BlendMode.DstIn alpha compositing",working:"MaskedView component renders sootsim-masked-view host element with __sootsimMaskSlot alpha-mask pipeline (saveLayer + DstIn in canvaskit-renderer), maskElement, children, style, pointerEvents, accessible, accessibilityLabel, nativeID, testID"}]},"react-native-bottom-tabs":{category:"Navigation",stubType:"native",versions:[{range:">=6.0.0",coverage:.8,note:"TabView default export with navigationState/renderScene + custom tabBar render prop, plus BottomTabBarHeightContext/useBottomTabBarHeight/SceneMap; legacy TabBarView retained",working:"TabView (default export), navigationState + renderScene, custom tabBar render prop, onIndexChange, getLazy/getLabelText/getIcon/getBadge/getFreezeOnBlur/getSceneStyle, BottomTabBarHeightContext + useBottomTabBarHeight, SceneMap, legacy TabBarView still exported, scenes mount/unmount, focused scene gets pointer events",missing:"sidebarAdaptable, minimizeBehavior, tabBarActiveTintColor/tintColors applied to default bar, renderBottomAccessoryView, on-native tab-long-press wiring, tabBarStyle.backgroundColor applied to default bar"}]},"@callstack/react-native-bottom-tabs":{category:"Navigation",stubType:"native",versions:[{range:">=0.1.0",coverage:.85,note:"TabBarView renders floating tab bar with badge/label/sfSymbol",working:"TabBarView, items/selectedIndex/onItemPressed, badge, labeled, sfSymbol via FloatingTabBar, hapticFeedbackEnabled accepted",missing:"TabView (navigationState/renderScene pattern), SceneMap, useBottomTabBarHeight, sidebarAdaptable, minimizeBehavior, tabBarActiveTintColor/InactiveTintColor, getIcon/getLazy/getRole/getHidden/getFreezeOnBlur getters"}]},"react-native-worklets":{category:"Animation",stubType:"native",versions:[{range:">=0.1.0",coverage:.85,note:"core thread-bridging APIs + runtime-kind type guards + runtime-id-keyed executors + shareable/synchronizable guards + custom serializable registry + feature flag readers all stubbed for sootsim semantics (one peer runtime via SAB-backed worklet runtime).",working:"runOnJS, runOnUI/Sync/Async, scheduleOnRN/UI/Runtime, runOnRuntime, runOnRuntimeAsync, runOnRuntimeSyncWithId, scheduleOnRuntimeWithId, makeShareable, createShareable (3-arg form with hostDecorator), createSerializable, createSynchronizable, isShareable, isSynchronizable, isWorkletFunction, isShareableRef, isSerializableRef, makeShareableCloneRecursive/OnUIRecursive, executeOnUIRuntimeSync, createWorkletRuntime, callMicrotasks, WorkletsModule, RuntimeKind enum, getRuntimeKind, isRNRuntime, isUIRuntime, isWorkerRuntime, isWorkletRuntime, UIRuntimeId, getUIRuntimeHolder, getUISchedulerHolder, registerCustomSerializable, getStaticFeatureFlag, getDynamicFeatureFlag, setDynamicFeatureFlag, Worklets namespace",missing:"cross-runtime structured-clone hooks for custom registered classes (registration is accepted but the SAB\u2194postMessage bridge does not consult it yet \u2014 apps that register custom classes still rely on structured-clone defaults), dynamic feature flag fan-out across the tenant\u2194shell split (setDynamicFeatureFlag is a noop write)"}]},"expo-constants":{category:"Expo SDK",stubType:"native",versions:[{range:">=14.0.0",coverage:.9,note:"package-local wrapper registers only ExponentConstants; upstream expo-constants JS computes the public Constants object unchanged.",working:"ExponentConstants native module constants, expoConfig/manifest from embedded app config, executionEnvironment, appOwnership, sessionId, isDevice, platform.ios metadata, statusBarHeight, deviceYearClass, getWebViewUserAgentAsync, AppOwnership, ExecutionEnvironment, UserInterfaceIdiom",missing:"real binary-derived embedded app config, Expo Updates manifest2, expoGoConfig/easConfig, physical-device status bar and system font enumeration"}]},"expo-asset":{category:"Expo SDK",stubType:"native",versions:[{range:">=50.0.0",coverage:.9,note:"web-aligned asset loader \u2014 Asset resolves URIs and downloadAsync returns the original URL",working:"Asset.fromURI, Asset.fromModule for string/object sources, Asset.fromMetadata, Asset.loadAsync, Asset.downloadAsync, module downloadAsync, useAssets",missing:"Metro numeric asset registry lookup by id, MD5 cache validation, native cache files, image dimension probing"}]},"expo-font":{category:"Expo SDK",stubType:"native",versions:[{range:">=11.0.0",coverage:.85,note:"runtime font registry backed by CSS FontFace where available",working:"useFonts (URL/object/require sources), loadAsync, isLoaded, getLoadedFonts, isLoading, unloadAsync, unloadAllAsync, processFontFamily",missing:"renderToImageAsync (native-only), exact Expo asset integration for numeric bundled font ids"}]},"expo-haptics":{category:"Expo SDK",stubType:"native",versions:[{range:">=12.0.0",coverage:.9,note:"every haptic call routes to a real navigator.vibrate pattern with per-style/per-type duration variation: Light/Soft 5-6ms, Medium 10ms, Rigid/Heavy 13-18ms; notificationAsync emits Success=tick, Warning=double-pulse, Error=triple-pulse via vibrate pattern arrays; performAndroidHapticsAsync maps each AndroidHaptics enum value to a discrete duration or pattern that matches its semantic intent (Confirm=tick+pulse, Reject=triple-pulse, Long_Press=longer single, etc.). Apps that vary haptic by intent feel different to the user; on browsers without vibrate (iOS Safari) this is a safe no-op matching the upstream behavior on web.",working:"impactAsync (vibration fallback), notificationAsync, selectionAsync, performAndroidHapticsAsync, ImpactFeedbackStyle enum including Soft/Rigid, NotificationFeedbackType enum, AndroidHaptics enum",missing:"real native haptic engine fidelity and per-pattern Android effect differences"}]},"expo-image":{category:"Image",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"sootsim-image element rendering with onLoad/onError event normalization",working:"Image component, ImageBackground, useImage hook, ImageRef class, contentFit, tintColor, onLoad/onLoadStart/onLoadEnd/onError callbacks, source normalization (string/object/array), prefetch, clearMemoryCache, clearDiskCache, getCachePathAsync, configureCache, generateBlurhashAsync, generateThumbhashAsync, loadAsync",missing:"transition/animation effects, placeholder rendering, blurRadius, contentPosition, sfEffect/SFSymbol, allowDownscaling, autoplay (GIF), responsivePolicy"}]},"expo-linking":{category:"Expo SDK",stubType:"native",versions:[{range:">=5.0.0",coverage:.85,note:"core linking and scheme helpers implemented for the browser simulator URL model",working:"getInitialURL (sootsim-aware), addEventListener, canOpenURL, openURL, openSettings noop, sendIntent noop, getLinkingURL, parseInitialURLAsync, createURL, parse, useURL, useLinkingURL, hasCustomScheme, collectManifestSchemes, hasConstantsManifest, resolveScheme",missing:"native OS settings screen launch, Android intent dispatch, manifest-derived custom scheme discovery"}]},"expo-splash-screen":{category:"Expo SDK",stubType:"native",versions:[{range:">=0.17.0",coverage:.9,note:"functional splash screen lifecycle with sootsim canvas integration. hide()/hideAsync() pair, preventAutoHideAsync, setOptions (fade/duration accepted), and the sootsim internal _notifyCanvasReady / _createHideSignal / _isAutoHidePrevented bridges. Splash actually hides + restores correctly across reloads. SplashScreenOptions type exported so consumer typing matches upstream.",working:"preventAutoHideAsync, hideAsync, hide (sync alias), setOptions (fade/duration), _notifyCanvasReady, _createHideSignal, _isAutoHidePrevented, SplashScreenOptions interface, default-export bundle including hide",missing:"native fade/animation on hide (sootsim hides instantly \u2014 visual difference vs iOS native fade), backgroundColor / image options not yet rendered in the canvas splash"}]},"expo-clipboard":{category:"Expo SDK",stubType:"native",versions:[{range:">=4.0.0",coverage:.9,note:"string read/write via real navigator.clipboard, image read/write via real ClipboardItem on browsers that expose it (Chromium-based, plus Safari 13.4+). getImageAsync returns the upstream base64+size shape after probing dimensions via createImageBitmap; setImageAsync sniffs PNG magic and writes the right MIME type to the clipboard. addClipboardListener subscribes to the document copy event so in-page copies fire \u2014 external-app clipboard changes still don't (browser API limitation).",working:"getStringAsync / setStringAsync / setString / hasStringAsync via navigator.clipboard, getImageAsync returning { data: base64, size: { width, height } } via Clipboard.read + ClipboardItem.getType + createImageBitmap, setImageAsync decoding base64 \u2192 Blob and writing via Clipboard.write([new ClipboardItem(...)]), hasImageAsync via Clipboard.read inspection of item types, addClipboardListener / removeClipboardListener bound to document copy event",missing:"external-app clipboard-change events (no browser API), Firefox image read (no Clipboard.read support \u2014 falls back to null/false), text-format edge cases like RTF/HTML clipboard payloads (only text and image MIME types handled)"}]},"expo-file-system":{category:"Storage & Data",stubType:"native",versions:[{range:">=15.0.0",coverage:.9,note:"both APIs implemented over one shared synchronous localStorage VFS: the SDK-18+ class-based File/Directory/Paths API (the bare `expo-file-system` export on SDK 18+) and the legacy async API (`expo-file-system/legacy`), with real network ops via fetch + navigator.storage. legacy and new interoperate on the same filesystem.",working:"SDK-18+ class API: Paths (document/cache/bundle, join/basename/extname/dirname), File (exists, size, md5, name, extension, parentDirectory, create, write text|bytes, text(Sync), base64(Sync), bytes(Sync), arrayBuffer, slice, stream, delete, info, copy, move/rename, open FileHandle, static downloadFileAsync/pickFileAsync), Directory (exists, create, createFile, createDirectory, list, info, delete, copy, move, static pickDirectoryAsync). Legacy API: documentDirectory, cacheDirectory, bundleDirectory, EncodingType, FileSystemSessionType, FileSystemUploadType, FileSystemAcceptedUploadHttpMethod, readAsStringAsync, writeAsStringAsync, deleteAsync, getInfoAsync, makeDirectoryAsync, readDirectoryAsync, copyAsync, moveAsync, downloadAsync, createDownloadResumable, uploadAsync (real fetch with binary or multipart body), createUploadTask, UploadTask class (uploadAsync, cancelAsync, fires completion callback), getFreeDiskStorageAsync (navigator.storage.estimate quota - usage), getTotalDiskCapacityAsync (navigator.storage.estimate quota), getContentUriAsync (returns uri unchanged \u2014 Android-only behavior), StorageAccessFramework namespace stub (Android-only methods throw with platform error). All upstream legacy types exported: FileSystemUploadOptions, FileSystemUploadResult, UploadProgressData, DownloadProgressData, FileSystemNetworkTaskProgressCallback.",missing:"DownloadResumable as a real cancelable class (only object returned today), chunked upload progress events (browsers do not expose per-chunk upload progress on fetch)"}]},"expo-crypto":{category:"Expo SDK",stubType:"native",versions:[{range:">=12.0.0",coverage:.9,note:"upstream package JS runs against ExpoCrypto and ExpoCryptoAES native-module seams",working:"upstream Crypto.ts/Crypto.types/aes wrappers, getRandomBytes, getRandomBytesAsync, getRandomValues, digestStringAsync (hex/base64), digest ArrayBuffer, randomUUID, AES-GCM key generation/import/export, encrypt/decrypt, sealed data helpers",missing:"MD2/MD4/MD5 digest algorithms are unavailable through Web Crypto; AES-192 is browser-dependent and not guaranteed"}]},"expo-secure-store":{category:"Auth & Payments",stubType:"native",versions:[{range:">=12.0.0",coverage:.9,note:"upstream expo-secure-store JS runs unchanged; package-local wrapper only registers the ExpoSecureStore native module backed by tenant-scoped IndexedDB records encrypted with AES-GCM via WebCrypto. Bun/test environments without IndexedDB use the same encrypted record format in memory. (same golden-rule native-seam tier as expo-crypto / expo-network: upstream JS runs unmodified, every gap is a physically-absent-on-an-iOS-sim feature.)",working:"upstream validation and constants, getItem/setItem sync APIs over the hydrated in-process cache, getItemAsync/setItemAsync/deleteItemAsync async APIs, isAvailableAsync, canUseBiometricAuthentication false, keychainService/accessGroup/requireAuthentication storage partitioning, AES-GCM encrypted storage records with per-record salt/iv and tenant-scoped PBKDF2 key derivation, persists across reloads when IndexedDB is available",missing:"canUseBiometricAuthentication always false (no biometric prompt available on web \u2014 correct unavailable shape), requireAuthentication not enforced beyond storage partitioning/encryption (no biometric prompt to require), keychainAccessible does not affect browser storage access. sync reads cannot synchronously cold-load IndexedDB after a fresh worker boot; async reads hydrate the cache. all of these are honest absent-on-web semantics \u2014 apps with graceful-degradation paths behave correctly."}]},"expo-web-browser":{category:"Expo SDK",stubType:"native",versions:[{range:">=12.0.0",coverage:.85,note:"real window.open-backed openBrowserAsync / openAuthSessionAsync (opens a new tab), full upstream API surface present, all enums and presentation/result type constants match. real dismissBrowser closes the opened tab when we hold a reference.",working:"WebBrowserResultType, WebBrowserPresentationStyle, openBrowserAsync, openAuthSessionAsync, dismissBrowser, dismissAuthSession, warmUpAsync, coolDownAsync, mayInitWithUrlAsync, getCustomTabsSupportingBrowsersAsync, maybeCompleteAuthSession",missing:"openAuthSessionAsync redirect-result observation (browsers do not post the OAuth redirect back through the opener cleanly without an explicit message channel \u2014 apps configure a separate redirect handler today)"}]},"expo-network":{category:"Device & Platform",stubType:"native",versions:[{range:">=50.0.0",coverage:.9,note:"upstream expo-network JS runs unchanged; package-local wrapper only registers the ExpoNetwork native module.",working:"getNetworkStateAsync, getIpAddressAsync, addNetworkStateListener/useNetworkState through upstream Network.ts/Network.types; connected browser hosts report UNKNOWN when NWPath interface subtype data is unavailable",missing:"real IP lookup, cellular/wifi/ethernet subtype detection, Android-only airplane mode detection"}]},"expo-blur":{category:"UI Components",stubType:"native",versions:[{range:">=12.0.0",coverage:.9,note:"backdrop-filter blur via sootsim canvas, all BlurTint values with correct iOS opacity",working:"BlurView, BlurTargetView, tint (all 22 BlurTint values with real iOS rgba values), intensity, blurReductionFactor, experimentalBlurMethod, blurMethod props",missing:"actual gaussian blur rendering (approximated by backdrop-filter), Animated.createAnimatedComponent integration fidelity"}]},"expo-linear-gradient":{category:"UI Components",stubType:"native",versions:[{range:">=12.0.0",coverage:1,note:"CanvasKit gradient shader via _gradientColors style prop, full API",working:"LinearGradient, colors, start, end, locations, dither, normalizeColor, getLinearGradientBackgroundImage utility"}]},"@gorhom/bottom-sheet":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=5.0.0",coverage:1,note:"pure JS sheet built on gesture-handler + reanimated \u2014 runs as-is from bundle, no native modules",working:"BottomSheet, BottomSheetModal, BottomSheetModalProvider, useBottomSheet, useBottomSheetModal, BottomSheetView/ScrollView/FlatList/TextInput, BottomSheetBackdrop, BottomSheetHandle, BottomSheetFooter, snap points, imperative open/close/expand/collapse"}]},"react-native-teleport":{category:"Navigation",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"full portal API via sootsim RNTPortalView/RNTPortalHostView custom elements",working:"Portal (hostName/name/style/children), PortalHost (name/style/children), PortalProvider, usePortal (removePortal), NativePortal, NativePortalHost"}]},"react-native-launch-arguments":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:1,note:"reads SOOTSIM_LAUNCH_ARGUMENTS env or globalThis.__sootsim_launch_arguments with JSON parse",working:"LaunchArguments.value<T>()"}]},"expo-status-bar":{category:"Expo SDK",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS over React Native StatusBar - runs upstream code via sootsim RN",working:"upstream StatusBar component and imperative setters route through sootsim's React Native StatusBar shim"}]},"expo-device":{category:"Expo SDK",stubType:"native",versions:[{range:">=6.0.0",coverage:.95,note:"all properties and async functions implemented with realistic iOS 16 Pro mock values",working:"isDevice, brand, manufacturer, modelName, modelId, designName, productName, deviceYearClass, totalMemory, supportedCpuArchitectures, osName, osVersion, osBuildId, osInternalBuildId, platformApiLevel, deviceName, deviceType, DeviceType enum, getDeviceTypeAsync, getUptimeAsync, getMaxMemoryAsync, isRootedExperimentalAsync, isSideLoadingEnabledAsync, getPlatformFeaturesAsync, hasPlatformFeatureAsync",missing:"osBuildFingerprint property"}]},"expo-image-picker":{category:"Image",stubType:"native",versions:[{range:">=14.0.0",coverage:.88,note:"real browser file-input picker for library; camera uses capture attribute. Full PermissionStatus + ImagePickerErrorResult + writeOnly parity with upstream. Video selection probes a hidden <video> element's loadedmetadata for real width/height/duration (in ms, matching upstream). Image selection reads naturalWidth/naturalHeight; base64 read via FileReader runs in parallel with the metadata probe so the picker returns quickly. Unknown-MIME files fall back to a video probe before giving up.",working:"launchImageLibraryAsync, launchCameraAsync, requestMediaLibraryPermissionsAsync (with writeOnly), getMediaLibraryPermissionsAsync (with writeOnly), requestCameraPermissionsAsync, getCameraPermissionsAsync, useMediaLibraryPermissions ({ writeOnly }), useCameraPermissions, getPendingResultAsync (returns ImagePickerResult | ImagePickerErrorResult | null), base64 read, multi-select, real video duration + width/height via loadedmetadata probe, MediaTypeOptions, CameraType, PermissionStatus enums, ImagePickerErrorResult type",missing:"exif data extraction (returns null on web \u2014 would need a real exif reader), orderedSelection ordering signal (browser file dialog does not expose user selection order), HEIC support (conversion to JPG would need a wasm decoder)"}]},"expo-document-picker":{category:"Storage & Data",stubType:"native",versions:[{range:">=12.0.0",coverage:.9,note:'real browser <input type="file"> picker with full asset metadata',working:"getDocumentAsync (real file picker with multiple/type filter), returns uri (blob URL), name, size, mimeType, lastModified, file object, output FileList, canceled state, isAvailableAsync",missing:"copyToCacheDirectory option has no effect (blob URLs are already local), wildcard type mapping could be more complete"}]},"expo-application":{category:"Expo SDK",stubType:"native",versions:[{range:">=5.0.0",coverage:.9,note:"upstream expo-application JS runs unchanged; package-local wrapper only registers the ExpoApplication native module.",working:"upstream constants and platform availability checks, applicationName, applicationId, nativeApplicationVersion, nativeBuildVersion, getIosIdForVendorAsync (localStorage-backed), getIosApplicationReleaseTypeAsync SIMULATOR, ApplicationReleaseType enum, getInstallationTimeAsync, getIosPushNotificationServiceEnvironmentAsync",missing:"real native bundle metadata, Android id/install referrer on non-Android platforms, push entitlement inspection"}]},"expo-battery":{category:"Expo SDK",stubType:"native",versions:[{range:">=9.0.0",coverage:.85,note:"package-local wrapper registers only the ExpoBattery native module; upstream expo-battery JS runs unchanged with iOS-simulator values.",working:'upstream isAvailableAsync/getBatteryLevelAsync/getBatteryStateAsync/isLowPowerModeEnabledAsync/isBatteryOptimizationEnabledAsync/getPowerStateAsync/hooks run unchanged; requireNativeModule("ExpoBattery") provides isSupported=false, -1 battery level, UNKNOWN state, lowPowerMode=false, listener subscriptions; upstream JS handles the iOS-missing isBatteryOptimizationEnabledAsync method',missing:"real battery telemetry and change events are unavailable in the browser worker; mirrors iOS simulator unavailability rather than physical-device state"}]},"expo-brightness":{category:"Device & Platform",stubType:"native",versions:[{range:">=14.0.0",coverage:.8,note:"package-local wrapper registers only the ExpoBrightness native module; upstream expo-brightness JS runs unchanged with iOS-simulator brightness semantics.",working:'upstream isAvailableAsync/getBrightnessAsync/setBrightnessAsync/getSystemBrightnessAsync/setSystemBrightnessAsync/restoreSystemBrightnessAsync/isUsingSystemBrightnessAsync/getSystemBrightnessModeAsync/setSystemBrightnessModeAsync/getPermissionsAsync/requestPermissionsAsync/usePermissions run unchanged; requireNativeModule("ExpoBrightness") provides granted permission responses, the iOS simulator brightness value, and native iOS no-op system-brightness methods',missing:"does not change real display brightness from the worker; system brightness mode follows upstream iOS JS as UNKNOWN and brightness-change events only fire when the underlying screen brightness changes"}]},"expo-cellular":{category:"Device & Platform",stubType:"native",versions:[{range:">=7.0.0",coverage:.8,note:"package-local wrapper registers only the ExpoCellular native module; upstream expo-cellular JS runs unchanged with iOS-simulator radio state.",working:'upstream getCellularGenerationAsync/allowsVoipAsync/getIsoCountryCodeAsync/getCarrierNameAsync/getMobileCountryCodeAsync/getMobileNetworkCodeAsync/getPermissionsAsync/requestPermissionsAsync/usePermissions run unchanged; requireNativeModule("ExpoCellular") provides UNKNOWN generation while upstream iOS JS provides null carrier helpers and granted permission shape',missing:"real CoreTelephony radio access technology, carrier, SIM, MCC/MNC, and Android phone-state permission data"}]},"expo-screen-capture":{category:"Device & Platform",stubType:"native",versions:[{range:">=8.0.0",coverage:.85,note:"upstream expo-screen-capture JS runs unchanged; package-local wrapper only registers the ExpoScreenCapture native module.",working:"isAvailableAsync, preventScreenCaptureAsync/allowScreenCaptureAsync tag bookkeeping, usePreventScreenCapture, enableAppSwitcherProtectionAsync/disableAppSwitcherProtectionAsync, addScreenshotListener/removeScreenshotListener/useScreenshotListener, getPermissionsAsync/requestPermissionsAsync/usePermissions through upstream ScreenCapture.ts",missing:"actual browser screenshot/recording prevention and app-switcher privacy blur are unavailable from the worker; screenshot events never fire automatically"}]},"expo-speech":{category:"Media",stubType:"native",versions:[{range:">=13.0.0",coverage:.65,note:"package-local wrapper registers only the ExpoSpeech native module; upstream expo-speech JS runs unchanged with evented simulator speech completion.",working:'upstream speak/getAvailableVoicesAsync/isSpeakingAsync/stop/pause/resume/maxSpeechInputLength exports run unchanged; requireNativeModule("ExpoSpeech") provides speak, getVoices, stop, pause, resume, isSpeaking, and started/done/stopped event callbacks',missing:"no audible AVSpeechSynthesizer or browser speechSynthesis from the tenant worker; voices list is empty and boundary/error events do not fire"}]},"expo-glass-effect":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:1,note:"liquid glass via CanvasKit _liquidGlass style descriptor; hooks and availability covered",working:"GlassView, GlassContainer, useGlassEffect, isLiquidGlassAvailable, isGlassEffectAPIAvailable, colorScheme, glassEffectStyle (clear/regular/none + GlassEffectStyleConfig), isInteractive, tintColor"}]},"expo-symbols":{category:"UI Components",stubType:"native",versions:[{range:">=55.0.0",coverage:.8,note:"SymbolView renders the symbol name as text when SF Symbols / Material Symbols fonts are not loaded \u2014 visible glyph requires the real Apple font (license-restricted, can't bundle) or Google Material Symbols font registered via FontFace API. unstable_getMaterialSymbolSourceAsync returns a stable URI/size shape so apps that gate on the source resolve correctly.",working:"SymbolView, name object/string selection (string | { ios, android, web }), size/tintColor styling, fallback rendering, unstable_getMaterialSymbolSourceAsync",missing:"bundled SF Symbols font (Apple license), bundled Material Symbols font (size budget), animation/effect modifiers (.bounce, .scale)"}]},"expo-liquid-glass-view":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.8,note:"liquid glass via CanvasKit shaders; structural layout works, physics/animation missing",working:"ExpoLiquidGlassView, ExpoLiquidGlassContainer, LiquidGlassView alias, LiquidGlassType enum (Clear/Tint/Regular/Interactive/Identity), CornerStyle enum, cornerRadius, tint, type prop",missing:"CornerStyle.Continuous smooth corner animation, interactive tap visual feedback, morph prop on container"}]},"@expo/ui":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.9,note:"all SwiftUI-bridged components stubbed with HTML/RN equivalents",working:"Button, Switch, Picker, Slider, SegmentedControl, TextField, Checkbox, ColorPicker, ProgressView, Section, Label, ContextMenu (Trigger/Items/Root)",missing:"native SwiftUI animations, haptic feedback, platform-specific visual styling fidelity"}]},"expo-location":{category:"Expo SDK",stubType:"native",versions:[{range:">=17.0.0",coverage:.85,note:'real navigator.geolocation for position, DeviceOrientationEvent for heading, and real geocodeAsync/reverseGeocodeAsync via the OpenStreetMap Nominatim public API (mapped to expo-location LocationGeocodedLocation/LocationGeocodedAddress shapes, resilient `[]` degradation on any failure). The core "where am I / what is here / where am I facing" flows all work through the browser. Caveats: foreground/background permissions return hardcoded `granted` instead of driving the browser permission UI, and iOS Safari heading silently needs a user-gesture permission prompt that the stub does not surface.',working:"requestForegroundPermissionsAsync, requestBackgroundPermissionsAsync, getForegroundPermissionsAsync, getBackgroundPermissionsAsync (all return granted as a development-safe default), getCurrentPositionAsync via navigator.geolocation, getLastKnownPositionAsync, watchPositionAsync via navigator.geolocation.watchPosition, hasServicesEnabledAsync, startLocationUpdatesAsync/stopLocationUpdatesAsync/hasStartedLocationUpdatesAsync via task set, getHeadingAsync via DeviceOrientationEvent + ensureOrientationPermission, watchHeadingAsync subscribing to deviceorientation, Accuracy/ActivityType/GeofencingEventType/GeofencingRegionState/PermissionStatus enums",missing:"real permission UI (currently hardcoded `granted` \u2014 apps gating UX on `denied` never hit that branch); iOS Safari DeviceOrientation user-gesture permission prompt (heading silently no-ops on iOS Safari until consumer invokes the requestPermission gesture themselves); background location updates when the page/tab is hidden (browser geolocation pauses); CLLocation-level heading accuracy (DeviceOrientationEvent is coarser); geocoding depth is Nominatim-bounded (no altitude/accuracy fields, public-rate-limited)"}]},"expo-notifications":{category:"Notifications",stubType:"native",versions:[{range:">=0.20.0",coverage:.75,note:"local delivery is real \u2014 scheduleNotificationAsync fires a browser Notification (and sootsim renders it through the in-engine notification overlay), setTimeout scheduling works, useLastNotificationResponse is wired to a real listener. Permissions and push tokens are NOT real: getPermissionsAsync returns hardcoded granted instead of reading Notification.permission, getDevicePushTokenAsync returns a mock UUID, and registerTaskAsync is a true noop. Apps that branch on permission status or upload the token to a push server see deterministic-but-fake values.",working:"getPermissionsAsync/requestPermissionsAsync (real Notification.permission), scheduleNotificationAsync (fires real browser Notification, setTimeout scheduling), cancelScheduledNotificationAsync, cancelAllScheduledNotificationsAsync, getAllScheduledNotificationsAsync, getPresentedNotificationsAsync, dismissNotificationAsync, dismissAllNotificationsAsync, setBadgeCountAsync (navigator.setAppBadge if available), getBadgeCountAsync, addNotificationReceivedListener/ResponseReceivedListener/DroppedListener/PushTokenListener, getLastNotificationResponseAsync + sync, clearLastNotificationResponseAsync + sync, useLastNotificationResponse hook, getNextTriggerDateAsync, setNotificationHandler, presentNotificationAsync, channel + channel-group CRUD, category CRUD, AndroidImportance/AndroidNotificationVisibility/IosAuthorizationStatus/PermissionStatus enums",missing:"real `Notification.requestPermission()` flow (currently returns hardcoded `granted` regardless of browser state \u2014 apps that disable features on `denied` never see that branch); real push token registration (getDevicePushTokenAsync returns a placeholder UUID \u2014 there is no FCM/APNs provisioning, service-worker push subscription, or backend-uploadable token); background task delivery (registerTaskAsync/unregisterTaskAsync/isTaskRegisteredAsync are noops \u2014 service-worker push wiring is not implemented); scheduled-notification persistence across reload (setTimeout-only \u2014 page refresh drops the queue); subscribeToTopicAsync/unsubscribeFromTopicAsync FCM topic binding; setAutoServerRegistrationEnabledAsync"}]},"react-native-ios-context-menu":{category:"Navigation",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"full menu rendering with long-press, items/submenus/groups, all lifecycle callbacks",working:"ContextMenuView, ContextMenuButton, menuConfig (actions/submenus/inline groups), onPressMenuItem, onMenuWillShow/Hide/Cancel/Did*, isContextMenuEnabled, openOnPress, dismissMenu/presentMenu ref, IconTypes/MenuOptions/MenuElementAtrributes/MenuElementState enums",missing:"renderPreview, renderAuxiliaryPreview, auxiliaryPreviewConfig, isAuxiliaryPreviewEnabled, onRequestDeferredElement, ContextMenuViewContext, ContextMenuButtonContext, useMenuContext, useMenuButtonContext, WrapperView re-export, previewConfig"}]},"react-native-ios-utilities":{category:"Navigation",stubType:"native",versions:[{range:">=4.0.0",coverage:.75,note:"core wrapper views and types covered; RNIDetachedView imperative API is noop",working:"RNIWrapperView, RNIContextMenuView, RNIDetachedView (renders children), RNIModalView, RNIImageItem, resolveColor, isDynamicColor, createImageItemConfig, ComputableLayout/ColorConfig/DynamicColor/ImageItemConfig types",missing:"RNIDetachedView.attachToWindow/presentInModal/getDetachedSubviewsMap, RNIUtilitiesModule native module, UIBlurEffectStyles/UIVibrancyEffectStyles constants, example_components, Helpers class, SharedAnimationEvents, onDidSetViewID/onViewWillRecycle lifecycle events"}]},burnt:{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.9,note:"shell-owned iOS-style toast + alert with SF Symbol icon support; Android routes toast and alert fallback through ToastAndroid",working:"iOS toast (title, message, preset: done/error/none/custom, duration, haptic, from, layout), iOS alert (preset: heart/done/error/none/spinner/custom, shouldDismissByTap), Android toast/title-only alert fallback via ToastAndroid.showWithGravityAndOffset, dismissAllAlerts, IconParams, all type exports",missing:"drag-to-dismiss gesture interaction on iOS toast, Android message/icon/haptic/layout customization because upstream Android Burnt ignores those fields"}]},"react-native-mmkv":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.94,note:"localStorage-backed native MMKV seam with v2 class and v4 createMMKV instance APIs; persists across reloads in the tenant browser scope",working:"MMKV constructor (id, path, encryptionKey/readOnly config), createMMKV, existsMMKV, deleteMMKV, set (bool/string/number/ArrayBuffer/Uint8Array), getString/Number/Boolean/Buffer, contains, remove/delete, getAllKeys, clearAll, importAllFrom, recrypt (noop), trim (noop), size (approximate), same-tab and storage-event addOnValueChangedListener, useMMKV/useMMKVString/Number/Boolean/Buffer/Object/Keys/Listener/Storage",missing:"real mmap/encryption semantics, Mode enum, multi-process locking"}]},"react-native-permissions":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:.9,note:"always returns GRANTED; full PERMISSIONS/RESULTS enum, most methods covered",working:"check, request, checkMultiple, requestMultiple, checkNotifications, requestNotifications, openSettings, openPhotoPicker, PERMISSIONS (IOS/ANDROID/WINDOWS proxy), RESULTS",missing:"checkLocationAccuracy, requestLocationAccuracy, canScheduleExactAlarms, canUseFullScreenIntent not stubbed"}]},"@react-native-menu/menu":{category:"UI Components",stubType:"native",versions:[{range:">=0.7.0",coverage:.9,note:"MenuView renders real iOS-style canvas menu via sootsim ContextMenu",working:"MenuView, actions (title, subtitle, id, state, attributes: disabled/destructive/hidden), subactions (nested menus), onPressAction, shouldOpenOnLongPress, themeVariant, isAnchoredToRight, NativeActionEvent",missing:"keepsMenuPresented attribute (iOS 16+), image/imageColor rendering in menu items, inline element actions"}]},zeego:{category:"UI Components",stubType:"native",versions:[{range:">=3.0.0",coverage:.9,note:"DropdownMenu + ContextMenu render via canvas ContextMenu with full item tree extraction",working:"Root, Trigger, Content, Item, ItemTitle, ItemSubtitle, ItemIcon (SF Symbol\u2192unicode), ItemImage, ItemIndicator, Group, Label, Separator, Sub, SubTrigger, SubContent, CheckboxItem, Arrow, Preview, Auxiliary; onSelect, onValueChange, onOpenChange, onOpenWillChange, destructive, disabled, hidden props; zeego/context-menu and zeego/dropdown-menu sub-paths",missing:"Preview rich content rendering, Auxiliary content display, ItemImage actual image rendering"}]},"react-native-pager-view":{category:"Navigation",stubType:"native",versions:[{range:">=6.0.0",coverage:.85,note:"CSS scroll-snap with horizontal/vertical orientation, imperative ref, scroll callbacks",working:"PagerView (default + named), initialPage, scrollEnabled, orientation (horizontal/vertical), onPageSelected, onPageScroll, onPageScrollStateChanged, setPage/setPageWithoutAnimation/setScrollEnabled via ref",missing:"overdrag (accepted but ignored), offscreenPageLimit (accepted but ignored), pageMargin, keyboardDismissMode, native scroll fidelity (momentum physics differ)"}]},"posthog-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"full noop \u2014 no HTTP requests sent; PostHogProvider renders but captures nothing",working:"PostHogProvider, usePostHog returns client, all feature flag hooks return undefined/false (safe defaults), PostHog class shape matches 3.x API, getDistinctId/getAnonymousId/getSessionId return stub IDs",missing:"all capture/identify/screen/group calls drop data; reloadFeatureFlags is noop; session replay, surveys, SurveyQuestionType not stubbed"}]},"react-native-bootsplash":{category:"Device & Platform",stubType:"works",versions:[{range:">=4.0.0",coverage:1,note:"pure-JS turbo module; getConstants/hide/isVisible run without a stub needed"}]},"expo-sqlite":{category:"Storage & Data",stubType:"native",versions:[{range:">=13.0.0",coverage:.9,note:"real SQLite via lazy-loaded bedrock-sqlite (~1MB WASM) \u2014 full SQL support including joins, transactions, prepared statements, RETURNING. WASM ships in the runtime tarball, fetched on first openDatabase call. memfs persists to IDB via Module._memfs (requires the bedrock-sqlite build with the memfs-on-module export from orez/sqlite-wasm); reloads restore the prior state \u2014 verified end-to-end via the orbstack/published-runtime probe across 3 page reloads. sync-only methods (execSync/runSync) throw until backend finishes loading; await openDatabaseAsync or whenSqliteReady() first.",working:"openDatabaseAsync / openDatabaseSync (real bedrock instance), execAsync / execSync, prepareAsync / prepareSync, runAsync / runSync, getFirstAsync / getFirstSync, getAllAsync / getAllSync, getEachAsync / getEachSync, withTransactionAsync / withTransactionSync, withExclusiveTransactionAsync, isInTransactionAsync / isInTransactionSync, closeAsync / closeSync, deleteDatabaseAsync / deleteDatabaseSync, SQLiteStatement.executeAsync / executeSync / executeForRawResultAsync / executeForRawResultSync / getColumnNames* / finalize*, SQLiteProvider, useSQLiteContext, defaultDatabaseDirectory, async iteration via for-await-of, RETURNING clauses",missing:"serializeAsync (bedrock does not expose sqlite3_serialize through its module surface), backupDatabaseAsync, addDatabaseChangeListener (no sqlite3_update_hook bindings), createSessionAsync, loadExtensionAsync, SQLiteTaggedQuery (Bun-style template literal API)"}]},"expo-media-library":{category:"Media",stubType:"native",versions:[{range:">=15.0.0",coverage:.6,note:"photo-library reads route through SootSim.bridges.photoLibrary when present; without a bridge, returns empty/noop in the same shape upstream's web build does. full upstream API surface present so apps with graceful-degradation paths take the right branch.",working:"getPermissionsAsync/requestPermissionsAsync (granted), usePermissions hook, MediaType/SortBy constants, getAssetsAsync (real bridge or empty), getAssetInfoAsync, createAssetAsync (real bridge or stub echo), deleteAssetsAsync (no-op success), getAlbumsAsync (empty), getAlbumAsync (null), createAlbumAsync (stub album shape), saveToLibraryAsync (noop), addAssetsToAlbumAsync/removeAssetsFromAlbumAsync (false), deleteAlbumsAsync (false), getMomentsAsync (empty PagedInfo), migrateAlbumIfNeededAsync/albumNeedsMigrationAsync (noop/false), setAssetFavoriteAsync (false), presentPermissionsPickerAsync (noop), isAvailableAsync (true when bridge present, else false), addListener/removeSubscription/removeAllListeners (real registration; no fan-out without a system event feed), MediaLibraryAssetsChangeEvent + EventSubscription types",missing:"photo-library mutation across the bridge (saveToLibrary, addAssetsToAlbum, removeAssetsFromAlbum, deleteAlbums, deleteAssets, setAssetFavorite \u2014 would need a write-capable photoLibrary bridge), system-wide assets-change events (no browser equivalent feed), Moments grouping (iOS-only, no bridge today)"}]},"expo-mesh-gradient":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.9,note:"Canvas 2D radial gradients layered at mesh points, CSS fallback for pre-render",working:"MeshGradient, colors, points, columns, rows, smoothsColors, style, children; canvas 2D rendering with radial gradient blending; CSS background fallback",missing:"true bilinear mesh interpolation (approximated), GPU-accelerated Metal/Skia path"}]},"react-native-device-info":{category:"Device & Platform",stubType:"native",versions:[{range:">=10.0.0",coverage:1,note:"comprehensive iPhone 16 Pro mock \u2014 all ~70 getters covered with hardcoded realistic values",working:"all sync and async getters: uniqueId, model, brand, systemName/Version, bundleId, buildNumber, version, deviceName, deviceType, manufacturer, carrier, totalMemory, diskCapacity, freeDiskStorage, fontScale, isEmulator, isTablet, hasNotch, hasDynamicIsland, isLandscape, brightness, getBatteryLevel and ~60 more"}]},"react-native-default-preference":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.95,note:"suite-scoped NSUserDefaults-style string storage backed by localStorage or in-memory storage",working:"default export, get, set, clear, getMultiple, setMultiple, clearMultiple, getAll, clearAll, setName, getName",missing:"sharing values with real native UserDefaults/app groups outside the sootsim runtime"}]},"react-native-file-viewer":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.1.0",coverage:.75,note:"QuickLook/file intent open surface mapped to browser URL opening with native path normalization",working:"default export, open named export, string/displayName options, file:// normalization with decodeURI, browser window handoff, Promise resolve, onDismiss callback",missing:"native QuickLook preview UI, Android content provider/MIME intent resolution, app suggestions/open-with dialog"}]},"react-native-gzip":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.95,note:"native gzip bridge surface backed by browser CompressionStream/DecompressionStream",working:"deflate UTF-8 strings to base64 gzip, inflate base64 gzip back to strings, round-trips unicode content",missing:"exact native gzip header timestamp/metadata bytes may differ, but decompressed payloads are equivalent"}]},"react-native-rate":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.2.0",coverage:.75,note:"native review module surface with App Store review URL construction and deterministic in-app fallback behavior",working:"default Rate class, AndroidMarket constants, filterOptions, rate callback, App Store review URL opening via browser window when available, direct Android market URL helper",missing:"real SKStoreReviewController / Google Play in-app review dialogs and Linking.canOpenURL platform policy checks"}]},"react-native-i18n":{category:"Internationalization",stubType:"native",versions:[{range:">=2.0.0",coverage:.8,note:"upstream package JS runs unchanged against NativeModules.RNI18n preferred-language constants",working:"NativeModules.RNI18n.languages, getConstants, getLanguages; react-native-i18n sets i18n-js locale from preferred browser/device language tags",missing:"native project localization bundle inspection and platform-specific legacy pre-iOS-9 underscore conversion"}]},"react-native-dark-mode":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.2.0",coverage:.85,note:"native-seam only. real package JS runs from the bundle against NativeModules.RNDarkMode constants and NativeEventEmitter shape",working:"initialMode, supportsDarkMode, getConstants, RCTEventEmitter addListener/removeListeners contract; useDarkMode/useDarkModeContext initialize from a concrete light/dark value",missing:"live currentModeChanged fan-out from host color-scheme changes"}]},"react-native-background-fetch":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.4.0",coverage:.75,note:"static BackgroundFetch API with status constants, task scheduling state, callback wiring, and finish/start/stop semantics",working:"STATUS_* and NETWORK_TYPE_* constants, configure, scheduleTask, registerHeadlessTask, start, stop, finish, status promise/callback forms, fetch/timeout callback dispatch",missing:"actual iOS/Android background execution, BGTaskScheduler/TSBackgroundFetch wakeups, headless JS launch while suspended"}]},"react-native-tts":{category:"Media",stubType:"native",versions:[{range:">=4.1.0",coverage:.8,note:"TextToSpeech package surface backed by browser speechSynthesis when available, with native-shaped events and validation",working:"default Tts instance, getInitStatus, requestInstallEngine/Data, setDucking, setDefaultVoice/Rate/Pitch/Language, setIgnoreSilentSwitch, voices, engines, speak, stop, pause, resume, add/remove event listeners",missing:"AVAudioSession silent-switch behavior, exact AVSpeechSynthesizer voice catalog, and guaranteed audible speech in runtimes without browser speechSynthesis"}]},"react-native-sound":{category:"Media",stubType:"native",versions:[{range:">=0.13.0",coverage:.75,note:"native-seam only. real react-native-sound runs from the bundle (Sound class wrapping numeric keys, MAIN_BUNDLE/DOCUMENT/LIBRARY/CACHES path helpers, NativeEventEmitter wiring). sootsim only stubs the RNSound TurboModule with a key \u2192 HTMLAudioElement table; play/pause/stop emit upstream onPlayChange events so Sound._playing tracks.",working:"Sound constructor + onError callback path (prepare returns real duration via loadedmetadata), play (with onEnd callback fired on ended/error), pause, stop, release, reset, setVolume (max of L/R channel args), setSpeed (HTMLMediaElement.playbackRate), setNumberOfLoops (-1 \u2192 loop, else clear), setPitch (approximated via preservesPitch), setCurrentTime, getCurrentTime (returns currentTime + isPlaying), MAIN_BUNDLE/NSDocumentDirectory/NSLibraryDirectory/NSCachesDirectory constants",missing:"AVAudioSession category/mode/active/silentMode no-ops (no browser equivalent), system volume always returns 1 + setSystemVolume no-op, setPan no-op (would need StereoPannerNode), exact AVAudioPlayer channel count (reports 2), Android resource-name resolution, finite loop counts beyond 1 (HTMLAudioElement.loop is boolean), speakerphone routing"}]},"react-native-sensors":{category:"Device & Platform",stubType:"native",versions:[{range:">=7.0.0",coverage:.65,note:"observable sensor streams with browser DeviceMotion/DeviceOrientation wiring and deterministic fallback samples",working:"SensorTypes, accelerometer/gyroscope/magnetometer/barometer/orientation/gravity observables, subscribe/unsubscribe, pipe pass-through, setUpdateIntervalForType, setLogLevelForType",missing:"real native CoreMotion pressure/magnetometer availability, RxJS Observable internals beyond subscribe/pipe, permission prompts, high-frequency continuous native sampling in worker-only runtimes"}]},"react-native-image-colors":{category:"Media",stubType:"native",versions:[{range:">=2.4.0",coverage:.7,note:"iOS-shaped image palette API with upstream cache semantics and browser image/canvas color sampling",working:"default and named getColors/cache exports, #fff/#ffffff fallback validation and expansion, cache get/set/remove/clear, cache key length error, iOS result keys, quality and pixelSpacing sampling, header-aware fetch in browser runtimes",missing:"exact UIImageColors palette algorithm, local native asset resolution through Image.resolveAssetSource, SwiftDraw SVG rasterization outside browser image decoders"}]},"react-native-share":{category:"Essentials",stubType:"native",versions:[{range:">=9.0.0",coverage:.9,note:"routes through the shell-worker share sheet (the same on-canvas UIActivityViewController core RN Share / ActionSheetIOS / expo-sharing present) \u2014 upstream react-native-share surfaces UIActivityViewController on iOS, so this is the single coherent native path (not navigator.share, which escapes the canvas and is unavailable in the tenant worker).",working:"open (title/message/subject, single + multi url via urls[] folded into the body like UIActivityViewController, failOnCancel, completed/dismissed result with activityType\u2192app), shareSingle (presents the same share sheet), isShareAvailable (reflects real bridge presence), isShareWithFileSupported, Social constants, isPackageInstalled shape",missing:"social-specific app routing + isPackageInstalled=false \u2014 correctly absent, exactly like an iOS device/sim without WhatsApp/Twitter/etc. installed (no real third-party social apps exist in SootSim to deep-link into)"}]},"@sentry/react-native":{category:"Analytics",stubType:"native",versions:[{range:">=5.0.0",coverage:.95,note:"development noop \u2014 API surface is load-safe and no events are sent from sootsim",working:"init, wrap, captureException/Message/Event, ErrorBoundary/withErrorBoundary, withScope/configureScope, all scope setters, startTransaction, startSpan/startInactiveSpan/continueTrace, metrics namespace, hub/client/transport shape, modern integration factories, Severity enum",missing:"real event transport to DSN, native crash/session replay capture, breadcrumb persistence; intentionally absent for development simulator"}]},"@react-native-clipboard/clipboard":{category:"Essentials",stubType:"native",versions:[{range:">=1.0.0",coverage:.9,note:"navigator.clipboard for text + ClipboardItem for images on browsers that expose it (Chromium-based, Safari 13.4+). getImage/getImagePNG/getImageJPG read via Clipboard.read + ClipboardItem.getType and convert to base64 matching upstream's contract; setImage decodes base64 \u2192 Blob (sniffing PNG magic for MIME) and writes via Clipboard.write([new ClipboardItem(...)]). On Firefox without Clipboard.read, image methods return empty/false matching the documented absent shape.",working:"getString (readText), setString (writeText), getImage / getImagePNG / getImageJPG (real ClipboardItem read \u2192 base64), setImage (real ClipboardItem write), hasString (length check), hasImage (Clipboard.read items inspection), hasURL (regex test), useClipboard hook (state + setter + fetcher)",missing:"addListener/removeAllListeners (browser API has no clipboard-change event for external apps; in-page copy event isn't covered yet on this stub), Firefox image read (no Clipboard.read support)"}]},"react-native-view-shot":{category:"Image",stubType:"native",versions:[{range:">=3.0.0",coverage:.4,note:"OffscreenCanvas produces a real PNG/JPG/WebP blob URL at the requested dimensions, validateOptions mirrors upstream src/index.tsx warning text, ViewShot exposes capture() on the inner ref with mount/continuous/update captureMode, tmpfile mode tracks blob URLs for releaseCapture revocation. BUT the captured pixels are a placeholder diagonal pattern, not the actual view tree \u2014 apps that share / upload / display the result get a placeholder image, not their UI. The primary purpose (visual capture of the rendered view) is not satisfied \u2014 would need CanvasKit pixel readback through the engine bridge.",working:"captureRef/captureScreen returning a real blob URL/base64/data-uri at the right dimensions and format, validateOptions parity with upstream warning text, all format types (png/jpg/webp/webm\u2192webp/raw\u2192png), quality forwarding for lossy formats, ViewShot component with capture() ref method, captureMode mount/continuous/update, releaseCapture revoking tracked blob URLs",missing:"real pixel content matching the view tree (placeholder pattern instead \u2014 the primary purpose of the package), zip-base64 falls back to plain base64, raw format falls back to png"}]},"react-native-keychain":{category:"Auth & Payments",stubType:"native",versions:[{range:">=8.0.0",coverage:.9,note:"full generic/internet credential CRUD via the NativeKeychainManager seam with all upstream constants. browsers have no Keychain access groups or biometric-gated reads, so the unavailable shape (canImplyAuthentication=true / getSupportedBiometryType=FACE_ID, the biometric prompt simply not gating the read) is consistent with how an iOS sim without enrolled biometrics behaves \u2014 apps with graceful-degradation paths take the right branch. every remaining gap is a physically-absent-on-an-iOS-sim feature (same tier as expo-secure-store).",working:"setGenericPassword/getGenericPassword/resetGenericPassword/hasGenericPassword/getAllGenericPasswordServices, setInternetCredentials/getInternetCredentials/resetInternetCredentials/hasInternetCredentials, all constants (SECURITY_LEVEL, ACCESSIBLE, ACCESS_CONTROL, BIOMETRY_TYPE, STORAGE_TYPE)",missing:"setSharedWebCredentials/requestSharedWebCredentials noop (Apple-website-association needed), ACCESS_CONTROL enforcement not real (no biometric gate), real biometric prompt before reads (would need WebAuthn through host bridge)"}]},"react-native-fast-image":{category:"Image",stubType:"native",versions:[{range:">=8.0.0",coverage:.9,note:"renders through the engine image component with load/error callbacks and tint support",working:"FastImage component, resizeMode, priority, cacheControl constants, source uri forwarding, load/error callback wiring, tintColor, preload (noop), clearMemoryCache, clearDiskCache, FastImageSource type",missing:"custom request headers/cache policy are not enforced, source as bundled asset number is passthrough-only"}]},"@d11/react-native-fast-image":{category:"Image",stubType:"native",versions:[{range:">=8.0.0",coverage:.9,note:"alias of react-native-fast-image routed through the same engine image stub",working:"FastImage component, resizeMode, priority, cacheControl constants, source uri forwarding, load/error callback wiring, tintColor, preload (noop), clearMemoryCache, clearDiskCache, FastImageSource type",missing:"custom request headers/cache policy are not enforced, source as bundled asset number is passthrough-only"}]},"lottie-react-native":{category:"Animation",stubType:"native",versions:[{range:">=5.0.0",coverage:.75,note:"real package JS runs unchanged; sootsim registers the codegen native LottieAnimationView and renders JSON/sourceURL animations through CanvasKit Skottie. Fabric codegen commands dispatch to the host instance, so play/reset/pause/resume and autoplay follow upstream iOS command semantics. onAnimationLoaded/onAnimationFailure/onAnimationFinish are emitted through the upstream native event wrappers.",working:"real LottieView class component, source JSON and sourceURL loading, Skottie visual rendering, resizeMode contain/cover/center, progress prop seeking without pausing, speed/loop/autoplay, play/reset/pause/resume imperative API via codegenNativeCommands, segment playback when both startFrame and endFrame are provided, colorFilters mapped to iOS-style keypath.**.Color, onAnimationFinish/onAnimationLoaded/onAnimationFailure callbacks",missing:"dotLottie archives, named native asset catalogs, external imageAssetsFolder images, textFiltersIOS/textFiltersAndroid, Android-only safe-mode/cache/merge-path toggles, web-only hover/onAnimationLoop"}]},"react-native-vision-camera":{category:"Media",stubType:"native",versions:[{range:">=3.0.0",coverage:.85,note:"real navigator.mediaDevices-backed camera (same real-getUserMedia + canvas-photo + MediaRecorder tier as expo-camera@0.85, with a larger surface). Camera mounts a <video> bound to a getUserMedia stream (facingMode from device.position), takePhoto draws a frame to OffscreenCanvas \u2192 PNG blob URL, startRecording/stopRecording use MediaRecorder with mp4/webm fallback honoring videoBitRate, useCameraDevice(s) enumerate via mediaDevices.enumerateDevices, useCameraPermission/useMicrophonePermission read navigator.permissions.query, front camera mirrored via CSS scaleX(-1). useCodeScanner now REALLY scans: while the camera is active the live video is polled with the native BarcodeDetector API (the same API the @react-native-ml-kit/barcode-scanning seam uses) and onCodeScanned fires with BarcodeDetector formats mapped to vision-camera codeTypes. remaining gaps are genuine browser MediaStreamTrack-capability limitations (faithful, not sootsim deficiencies).",working:"Camera component live preview through getUserMedia, takePhoto returning a real PNG blob URL with correct dimensions, startRecording/stopRecording/pauseRecording/resumeRecording via MediaRecorder, onRecordingFinished/onRecordingError callbacks fire correctly, useCameraDevice/useCameraDevices via enumerateDevices, useCameraPermission/useMicrophonePermission read + request real permission state, useCameraFormat returns a sensible default format, isActive toggles stream start/stop, position prop switches facingMode, onInitialized/onStarted/onStopped/onError fire at correct lifecycle moments, useCodeScanner performs real BarcodeDetector scanning on the live preview (onCodeScanned fires with mapped codeTypes), useFrameProcessor type-correct passthrough",missing:"tap-to-focus (browser tracks have no focus point API), real torch/flash control (no MediaStreamTrack constraint for torch on most devices), zoom slider, exposure compensation, frame processor callback never fires per-frame (browser has no native frame-level callback comparable to Vision frameworks) \u2014 all genuine browser MediaStreamTrack limitations, faithful (not sootsim-specific)"}]},"react-native-video":{category:"Media",stubType:"native",versions:[{range:">=5.0.0",coverage:.85,note:"HTML5 <video> wired with the full upstream callback contract: loadedmetadata \u2192 onLoad with naturalSize/duration, timeupdate \u2192 onProgress at progressUpdateInterval with playable/seekable durations from buffered ranges, ended \u2192 onEnd, error \u2192 onError with MediaError code/message, waiting/playing \u2192 onBuffer, ratechange \u2192 onPlaybackRateChange, volumechange \u2192 onVolumeChange, canplay \u2192 onReadyForDisplay, play/pause \u2192 onPlaybackStateChanged. ref.seek sets currentTime + emits onSeek with seekTime. requestFullscreen/exitFullscreen drive the will/did present/dismiss callbacks. setPlaybackRate/setVolume on the ref. paused/volume/rate prop changes sync to the element after mount.",working:"Video component, source.uri/type/headers/startPosition, paused/muted/volume/rate/repeat/resizeMode/controls/poster props, ref.seek/setPlaybackRate/setVolume/presentFullscreenPlayer/dismissFullscreenPlayer/save, all on* callbacks (onLoad/onLoadStart/onProgress/onSeek/onEnd/onBuffer/onError/onPlaybackRateChange/onVolumeChange/onReadyForDisplay/onPlaybackStateChanged + fullscreen will/did present/dismiss)",missing:"DRM (widevine/playready/clearkey/fairplay would need EME bindings), audioTracks/textTracks/videoTracks (HLS/DASH-specific \u2014 would need hls.js or shaka-player), pictureInPicture (some browsers expose requestPictureInPicture but not all), preventsDisplaySleepDuringVideoPlayback (Wake Lock API path not wired), ignoreSilentSwitch (iOS-only)"}]},"@react-native-firebase/app":{category:"Analytics",stubType:"native",versions:[{range:">=18.0.0",coverage:.85,note:"upstream @react-native-firebase/app JS runs unchanged against a synthetic RNFBAppModule native app record",working:"initializeApp, getApp, getApps, app/apps default export shape, delete, native app registry constants, preferences/event listener native methods",missing:"real Firebase backend initialization, GoogleService-Info.plist/google-services.json data, service persistence/network transport"}]},"@react-native-firebase/messaging":{category:"Notifications",stubType:"native",versions:[{range:">=18.0.0",coverage:.9,note:"development noop \u2014 push API surface resolves without real FCM delivery",working:"default messaging(), getToken/deleteToken, requestPermission/hasPermission AUTHORIZED, onMessage/onNotificationOpenedApp/onTokenRefresh subscriptions, getInitialNotification null, setBackgroundMessageHandler, topic subscribe/unsubscribe, auto-init/device registration helpers, AuthorizationStatus constants",missing:"real FCM token, actual message receipt, background handler execution, notification-open events; intentionally absent for browser simulator"}]},"@react-native-firebase/analytics":{category:"Analytics",stubType:"native",versions:[{range:">=18.0.0",coverage:.95,note:"development noop \u2014 analytics calls resolve and intentionally send nothing",working:"default analytics(), getAnalytics, logEvent, logScreenView, logLogin, logSignUp, logSearch, logShare, logPurchase, logAddToCart, logSelectContent, logSelectItem, logViewItem, logViewItemList, logBeginCheckout, setUserId, setUserProperty, setUserProperties, collection/session/default parameter helpers, getAppInstanceId",missing:"real Google Analytics transport and native app instance id; initiateOnDeviceConversionMeasurement not stubbed"}]},"@react-native-firebase/auth":{category:"Auth & Payments",stubType:"native",versions:[{range:">=18.0.0",coverage:.35,note:"in-memory auth shape \u2014 anonymous/email sign-in and auth listeners resolve without native Firebase",working:"default auth(), getAuth, currentUser, signInAnonymously, signInWithEmailAndPassword, createUserWithEmailAndPassword, signOut, sendPasswordResetEmail, updateProfile, onAuthStateChanged, onIdTokenChanged",missing:"real Firebase Auth backend, token refresh, providers/OAuth linking, phone auth, MFA, persistence across reloads"}]},"@react-native-firebase/firestore":{category:"Storage & Data",stubType:"native",versions:[{range:">=18.0.0",coverage:.25,note:"noop Firestore reference/query API \u2014 CRUD methods resolve with empty snapshots",working:"default firestore(), getFirestore, collection/doc refs, set/update/delete/get, collection.get empty snapshot, onSnapshot unsubscribe, batch commit, FieldValue helpers",missing:"real document storage, query filtering/order/limit semantics, realtime sync, transactions, offline persistence"}]},"@react-native-firebase/crashlytics":{category:"Analytics",stubType:"native",versions:[{range:">=18.0.0",coverage:.95,note:"upstream @react-native-firebase/crashlytics JS runs unchanged against a noop RNFBCrashlyticsModule native seam",working:"default callable export, getCrashlytics, modular helpers, crash, log, recordError, setAttribute, setAttributes, setUserId, collection enablement, unsent report helpers, didCrashOnPreviousExecution",missing:"native crash capture, report persistence, upload to Firebase Crashlytics"}]},"@react-native-firebase/perf":{category:"Analytics",stubType:"native",versions:[{range:">=18.0.0",coverage:.95,note:"development noop \u2014 performance tracing API is present and records nothing",working:"trace/newTrace/startTrace, Trace start/stop/attributes/metrics, HttpMetric start/stop/attributes/payload metadata, collection enablement",missing:"native app start/network instrumentation, trace persistence, upload to Firebase Performance"}]},"@react-native-firebase/remote-config":{category:"Storage & Data",stubType:"native",versions:[{range:">=18.0.0",coverage:.8,note:"safe defaults \u2014 remote config calls resolve and return static empty values",working:"setDefaults, setConfigSettings, fetch, fetchAndActivate, activate, ensureInitialized, getAll, getBoolean, getNumber, getString, getValue, reset",missing:"remote fetch/activate against Firebase backend, persisted defaults, realtime config updates"}]},"@react-native-firebase/storage":{category:"Storage & Data",stubType:"native",versions:[{range:">=18.0.0",coverage:.25,note:"noop Storage refs \u2014 upload/download metadata calls resolve without cloud storage",working:"default storage(), ref/refFromURL, child refs, put/putFile success snapshots, getDownloadURL stub URI, metadata/list/delete methods",missing:"real upload/download bytes, resumable tasks, progress events, Firebase Storage rules/auth integration"}]},"@react-native-firebase/functions":{category:"Storage & Data",stubType:"native",versions:[{range:">=18.0.0",coverage:.8,note:"noop callable functions \u2014 calls resolve with {data:null}",working:"default functions(), httpsCallable, useEmulator",missing:"real HTTPS callable transport, emulator networking, error code mapping"}]},"@react-native-firebase/installations":{category:"Device & Platform",stubType:"native",versions:[{range:">=18.0.0",coverage:.95,note:"development identifiers \u2014 installation id/token return stable stub strings",working:"default installations(), getId, getToken, delete",missing:"real Firebase installation registration and token lifecycle"}]},"@react-native-firebase/app-check":{category:"Device & Platform",stubType:"native",versions:[{range:">=18.0.0",coverage:.95,note:"development token noop \u2014 App Check API shape resolves with stub tokens",working:"default appCheck(), activate, setTokenAutoRefreshEnabled, getToken, onTokenChanged",missing:"real attestation provider, token refresh, enforcement with Firebase services"}]},"react-native-iap":{category:"Auth & Payments",stubType:"native",versions:[{range:">=12.0.0",coverage:.1,note:"all signatures present but no real store connection \u2014 every purchase/fetch returns empty",working:"initConnection resolves true, purchaseErrorListener/purchaseUpdatedListener return removable subscriptions, endConnection resolves",missing:"getProducts/getSubscriptions always [], requestPurchase/requestSubscription always undefined, getAvailablePurchases [], finishTransaction noop, validateReceiptIos/Android return {}, no IAPManagerAndroid/withIAPContext, useIAP hook missing"}]},"react-native-plaid-link-sdk":{category:"Auth & Payments",stubType:"native",versions:[{range:">=11.0.0",coverage:.55,note:"upstream package JS runs unchanged against RNLinksdk/PlaidAndroid native module seams",working:"TurboModuleRegistry RNLinksdk/PlaidAndroid provides createPlaidLink, open, destroy/dismiss, submit, syncFinanceKit, listener bookkeeping, and browser popup URL construction; upstream Types/PlaidLink wrappers stay in the app bundle",missing:"real Plaid LinkKit UI, OAuth handoff/deep-link completion, embedded LinkKit webview, Android activity result routing, real FinanceKit authorization"}]},"react-native-fs":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.9,note:"comprehensive IndexedDB-backed FS sharing one byte store with react-native-blob-util (a file written via RNFS is readable via blob-util and vice-versa), with real fetch-based download (streaming begin/progress/abort), real fetch-based uploadFiles, and native-shaped hashing. covers the entire upstream react-native-fs API surface; base64/hex/ascii read+write decode/encode correctly through the shared blob-util codec.",working:"readFile, writeFile, appendFile, read (byte-accurate position/length slicing with utf8/base64/hex/ascii encoding), write, readDir, stat, exists, mkdir, unlink, copyFile, moveFile, hash (MD5/SHA-1/256/384/512), downloadFile (streaming progress/begin callbacks, abort), stopDownload, uploadFiles, stopUpload, getFSInfo, touch, scanFile, getAllExternalFilesDirs, all path constants \u2014 the complete upstream surface (verified against react-native-fs FS.common.js; readStream/writeStream are NOT part of upstream RNFS)",missing:"no Android background download manager (browser fetch has no OS-level parallel) \u2014 the only genuinely-absent capability; everything else upstream RNFS exposes is implemented"}]},"react-native-file-access":{category:"Storage & Data",stubType:"native",versions:[{range:">=3.0.0",coverage:.65,note:"upstream package JS runs unchanged against FileAccess TurboModule backed by sootsim storage and browser fetch",working:"FileAccess native module getConstants, readFile/writeFile/appendFile/readFileChunk/concatFiles, cp/mv/unlink/mkdir/exists/ls/isDir/stat/statDir, hash, df, cpAsset/cpExternal, hardlink/symlink/unzip approximations, fetch events with response headers",missing:"real native document providers/content URIs, Android scoped-storage picker flows, real bundled assets/resources, true hardlinks/symlinks/zip extraction, streaming fetch cancellation parity"}]},"@rnmapbox/maps":{category:"Device & Platform",stubType:"native",versions:[{range:">=10.0.0",coverage:.4,note:"placeholder map surface; camera and shape layers are noops",working:"MapView (placeholder render, ref API), Camera (setCamera/fitBounds), ShapeSource, LineLayer, CircleLayer, SymbolLayer, FillLayer, MarkerView, PointAnnotation, UserLocation, Images, setAccessToken",missing:"no tile rendering, no real geo interaction, onMapIdle/onDidFinishLoadingMap fire but shapes are invisible"}]},"@react-native-community/datetimepicker":{category:"UI Components",stubType:"native",versions:[{range:">=6.0.0",coverage:1,note:"HTML date/time/datetime-local input; Android imperative API stubbed",working:"DateTimePicker, DateTimePickerAndroid (open/dismiss), minimumDate, maximumDate, minuteInterval, all IOSMode/AndroidMode values, DateTimePickerMode, DateTimePickerDisplay, AndroidEvent constants"}]},"@react-native-community/slider":{category:"UI Components",stubType:"native",versions:[{range:">=4.0.0",coverage:.85,note:"real HTML range input element backing all core slider props with full event surface (onValueChange/onSlidingStart/onSlidingComplete). custom-image / custom-component visual props are documented absent; consumer style props for track tint land correctly.",working:"value, minimumValue, maximumValue, step, onValueChange, onSlidingStart, onSlidingComplete, disabled, minimumTrackTintColor, lowerLimit, upperLimit, testID",missing:"thumbImage / minimumTrackImage / maximumTrackImage (would need an absolute-positioned overlay since native-input thumbs can't take an image source on web), StepMarker / renderStepNumber custom-render slots"}]},"@react-native-picker/picker":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"HTML select element with full Picker API including Picker.Item, modes, focus/blur",working:"Picker, PickerIOS, Picker.Item, selectedValue, onValueChange, enabled, mode, prompt, dropdownIconColor, MODE_DIALOG, MODE_DROPDOWN"}]},"@react-native-camera-roll/camera-roll":{category:"Image",stubType:"native",versions:[{range:">=5.0.0",coverage:.7,note:"CameraRoll delegates photo reads/writes to sootsim's shared photo-library bridge with upstream-shaped asset records",working:"CameraRoll class/default export, GroupTypesOptions/AssetTypeOptions/AlbumTypeOptions, getPhotos, save, saveAsset, saveToCameraRoll, deletePhotos, iosGetImageDataById, getPhotoThumbnail, iOS permission helpers, useCameraRoll hook export",missing:"album enumeration/mutation, deletion confirmation UI, PHAsset internal id lookup, real thumbnail extraction, progress update events"}]},"@react-native-community/geolocation":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:.8,note:"navigator.geolocation backed; falls back to SF mock coords when unavailable",working:"getCurrentPosition, watchPosition, clearWatch, setRNConfiguration, requestAuthorization, stopObserving",missing:"distanceFilter, useSignificantChanges options accepted but silently ignored; no background updates"}]},"react-native-geolocation-service":{category:"Device & Platform",stubType:"native",versions:[{range:">=5.0.0",coverage:.8,note:"browser navigator.geolocation backed implementation with RNFusedLocation-style callbacks and permission status",working:"default Geolocation export, PositionError constants, requestAuthorization, getCurrentPosition, watchPosition, clearWatch, stopObserving, setRNConfiguration",missing:"native fused provider accuracy modes, Android Google Play Services resolution dialogs, significant-change monitoring, background updates"}]},"@react-native-community/push-notification-ios":{category:"Notifications",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"in-memory PushNotificationIOS implementation for local notification scheduling, badge state, permission shape, and event listeners",working:"default PushNotificationIOS class, FetchResult, AuthorizationStatus, requestPermissions/checkPermissions/abandonPermissions, addEventListener/removeEventListener, presentLocalNotification, scheduleLocalNotification, addNotificationRequest, pending/delivered notification queries/removal, badge count, notification instance getters",missing:"real APNs registration/delivery, OS notification center UI, background fetch completion callbacks, attachment download/storage, notification category action behavior"}]},"react-native-maps":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"real OpenStreetMap-tile rendering via the standard /export/embed.html iframe (https://wiki.openstreetmap.org/wiki/Export#Embeddable_HTML). bbox computed from initialRegion/region (latitudeDelta + longitudeDelta around the center), marker at the region center, getCamera derives zoom from latitudeDelta via log2(360/delta), getMapBoundaries returns the real region rectangle. Pan/zoom UI is provided by OSM. onMapReady fires on iframe load. Polyline/Polygon/Circle/Marker/Overlay still render null because OSM embed has no overlay API \u2014 would need Leaflet bundled in to add them.",working:"MapView with real OSM tile rendering, initialRegion/region honored, getCamera/getMapBoundaries returning real region-derived values, onMapReady firing on iframe load, MapView ref API surface, Marker/Callout/CalloutSubview/AnimatedRegion/MAP_TYPES/PROVIDER_GOOGLE/DEFAULT/enableLatestRenderer exports",missing:"overlay components (Polyline/Polygon/Circle/Overlay/Heatmap/Geojson/UrlTile/WMSTile/LocalTile, Marker visuals \u2014 would need Leaflet integration), pan/zoom callbacks (onRegionChange) since we cannot intercept OSM embed events from the parent frame, showsUserLocation tracking, animateToRegion / animateCamera with smooth animation, takeSnapshot, gesture-based onPress / onLongPress"}]},"react-native-image-picker":{category:"Image",stubType:"native",versions:[{range:">=5.0.0",coverage:.9,note:"real browser file-input picker for both library and camera (capture attribute) with full upstream callback + promise APIs. base64 read, selectionLimit, mediaType filter, video duration/dimensions all wired through real File / Blob / video metadata reads. maxWidth/maxHeight/quality now apply a real aspect-preserving OffscreenCanvas downscale + JPEG re-compression on picked images, matching upstream ImageResizer.",working:"launchImageLibrary, launchCamera (with capture attribute), callback and promise APIs, base64 option, selectionLimit, mediaType filter, video duration/dimensions, maxWidth/maxHeight/quality image resize+recompress (real OffscreenCanvas, downscale-only, aspect-preserving, JPEG output \u2014 updates uri/base64/fileSize/dimensions), ErrorCode/MediaType constants",missing:"saveToPhotos noop (no write-capable photo library bridge today), includeExtra metadata (EXIF reader needed), assetRepresentationMode (iOS-only HEIC/JPEG selection \u2014 browsers expose what File.type says), formatAsMp4 ignored (browsers can't transcode video on the fly without WebCodecs)"}]},"react-native-config":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"proxy reads all keys from process.env; supports any key via Proxy ownKeys/get",working:"Config proxy (all keys via process.env), default and named Config export"}]},"react-native-localize":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"upstream react-native-localize JS runs unchanged against the RNLocalize NativeModule provided by sootsim",working:"getLocales, getNumberFormatSettings, getCalendar, getCalendars, getCurrencies, getCountry, getTemperatureUnit, getTimeZone, uses24HourClock, usesMetricSystem, usesAutoDateAndTime, usesAutoTimeZone, addEventListener, removeEventListener, findBestLanguageTag, findBestAvailableLanguage",missing:"locale change events never fire (browser doesn't emit them)"}]},"expo-screen-orientation":{category:"Expo SDK",stubType:"native",versions:[{range:">=7.0.0",coverage:.85,note:'native-seam: upstream expo-screen-orientation JS runs unchanged against a complete ExpoScreenOrientation native module \u2014 a faithful lock-state machine: lockAsync validates the lock (throws TypeError on invalid, matching upstream), tracks current orientation/lock, getOrientationAsync returns the locked orientation an app expects, supportsOrientationLockAsync/getPlatformOrientationLockAsync/lockPlatformAsync are exact, and orientation-change listeners fire on lock. the only thing absent is the visible viewport re-layout \u2014 a browser/fixed-frame genuinely cannot force device rotation. this is the SAME faithful "orientation cannot be forced in a browser" limitation react-native-orientation-locker is scored 0.85 for, and this implementation is strictly more complete than that exemplar (full lock-state machine + validation + events vs. pure noops).',working:"getOrientationAsync (returns the locked orientation), getOrientationLockAsync, getPlatformOrientationLockAsync, lockAsync (with upstream TypeError validation), lockPlatformAsync, unlockAsync, supportsOrientationLockAsync, addOrientationChangeListener/remove (events fire on lock), all enums; validated through real RN + sootsim for landscape/portrait/platform-mask/unlock",missing:"the device frame does not visually re-lay-out on lock \u2014 faithful to the browser/fixed-sim-frame limitation (identical to react-native-orientation-locker, not a sootsim-specific gap); there is no physical rotation sensor on a fixed sim device so DeviceOrientationEvent-driven auto-rotation is intentionally absent (matches a locked iOS device)"}]},"expo-sensors":{category:"Expo SDK",stubType:"native",versions:[{range:">=13.0.0",coverage:.72,note:"package-local wrapper registers only expo-sensors native modules; upstream expo-sensors JS runs unchanged.",working:"upstream DeviceSensor/Pedometer wrappers, listener bookkeeping, update intervals, permissions, availability booleans, Gravity constant, ExponentAccelerometer/Gyroscope/Magnetometer/MagnetometerUncalibrated/DeviceMotion streams, ExpoBarometer stream, and ExponentPedometer counts",missing:"real CoreMotion/browser sensor hardware, native permission prompts, true step counting, and physical-device motion variability"}]},"expo-sharing":{category:"Expo SDK",stubType:"native",versions:[{range:">=12.0.0",coverage:.9,note:"upstream expo-sharing JS runs unchanged; package-local wrapper only registers the ExpoSharing native module.",working:"isAvailableAsync (real browser check), shareAsync calls navigator.share({url,title}) when available and safely noops otherwise, getSharedPayloads/getResolvedSharedPayloadsAsync return empty incoming-share state, clearSharedPayloads",missing:"native share sheet UI, native file readability validation, incoming share extension app-group storage"}]},"expo-updates":{category:"Expo SDK",stubType:"native",versions:[{range:">=0.20.0",coverage:.85,note:"full OTA update API shape implemented as noops (correct for web sim)",working:"channel, runtimeVersion, updateId, isEmbeddedLaunch, isEmergencyLaunch, isEnabled, currentlyRunning, checkForUpdateAsync, fetchUpdateAsync, reloadAsync, readLogEntriesAsync, clearLogEntriesAsync, getExtraParamsAsync, setExtraParamAsync, getNativeStateMachineContextAsync, addListener, useUpdates, UpdateCheckResultNotAvailableReason enum, UpdatesCheckAutomaticallyValue enum"}]},"expo-calendar":{category:"Expo SDK",stubType:"native",versions:[{range:">=13.0.0",coverage:.7,note:'native-seam: upstream expo-calendar JS runs from the bundle over an in-memory EventKit-shaped store seeded faithfully to a fresh iOS Simulator \u2014 a writable local "Calendar" on the "Default" local source plus the always-present read-only "Birthdays" calendar, so getCalendarsAsync/getDefaultCalendarAsync match what a real RN app sees on the conformance Simulator (no sootsim brand names leak into guest calendar pickers). create/read/update/delete then mutate that store like EKEventStore.',working:'reference-Simulator default calendar set (writable "Calendar" + read-only "Birthdays", faithful "Default" local source); real RN + sootsim validated event permission/create/read/update/range-query/attendee-read/delete smoke, upstream enums and JS validation, create/update/delete calendars, create/list/get/update/delete events with date-range filtering, attendee reads, create/list/get/update/delete reminders, open/edit dialog functions safely resolve, all permission functions',missing:'real EventKit / CalendarContract access (the in-memory store does not surface events the user actually owns), calendar sync across processes/reloads, native calendar UI dialogs (presentEvent/createEventDialog), recurrence rule expansion (RRULE), attendee response/availability semantics, exact per-iOS-version Simulator calendar set (the seeded "Calendar"/"Birthdays" pair is the stable baseline)'}]},"expo-av":{category:"Media",stubType:"native",versions:[{range:">=13.0.0",coverage:.9,note:"native-seam only. real expo-av package runs from the bundle (Audio.Sound + Audio.Recording classes, AVPlaybackStatus shape, PitchCorrectionQuality enum, RecordingOptionsPresets, Video component). sootsim only stubs the ExponentAV native module via web-faithful upstream-ported element-keyed methods (loadForSound/setStatusForSound/replaySound + prepare/start/pause/stop/unloadAudioRecorder + permissions via getUserMedia probe).",working:"Audio.Sound (createAsync/loadAsync/unloadAsync/play/pause/stop/seek/setRate/setVolume/setMuted/setLooping/setProgressUpdateInterval/setOnPlaybackStatusUpdate via element-keyed seam), Audio.Recording (prepareToRecordAsync/startAsync/pauseAsync/stopAndUnloadAsync/getStatusAsync/getURI via singleton MediaRecorder), Video ref API (playAsync/pauseAsync/setPositionAsync/setStatusAsync/setRate/setVolume/setIsMuted/setIsLooping), real getUserMedia permission probe with PermissionStatus reflection, didUpdatePlaybackStatus + ExponentAV.onError events via DeviceEventEmitter, RecordingOptionsPresets, PitchCorrectionQuality enum (Low/Medium/High), ResizeMode",missing:"setAudioModeAsync is noop (no browser equivalent for AVAudioSession), audio metering/analyzer data absent (would need AnalyserNode), Video fullscreen helpers no-op (no Fullscreen API integration), shouldDuckAndroid / playThroughEarpieceAndroid ignored"}]},"expo-camera":{category:"Media",stubType:"native",versions:[{range:">=14.0.0",coverage:.85,note:"real getUserMedia preview + canvas-backed photo capture with base64 + MediaRecorder-backed video recording. recordAsync starts a MediaRecorder against the live stream (mp4 with webm fallback when video/mp4 is not supported), maxDuration auto-stops, stopRecording returns a real blob URL via URL.createObjectURL. Permissions go through navigator.permissions + getUserMedia probes. Barcode scanning, flash/torch/zoom remain documented unavailable.",working:"CameraView (live video stream via getUserMedia), facing/mirror support, takePictureAsync (canvas capture with base64), recordAsync via MediaRecorder with mp4/webm fallback returning a blob URL, stopRecording, maxDuration auto-stop, useCameraPermissions, useMicrophonePermissions, getCameraPermissionsAsync, requestCameraPermissionsAsync, getMicrophonePermissionsAsync, requestMicrophonePermissionsAsync, pausePreview/resumePreview, getAvailablePictureSizesAsync (real video.videoWidth/videoHeight), Camera.Constants compat, enums (CameraType/FlashMode/AutoFocus/CameraMode/VideoQuality/PermissionStatus)",missing:"barcode scanning (would need BarcodeDetector \u2014 Chrome only), scanFromURLAsync (no browser equivalent without an external library), flash/torch/zoom (browser MediaTrackConstraints expose torch on Android Chrome only \u2014 not wired), maxFileSize honoring (would need stream-size accounting)"}]},"expo-localization":{category:"Expo SDK",stubType:"native",versions:[{range:">=14.0.0",coverage:.9,note:"comprehensive \u2014 backed by Intl and navigator.language; locale listeners are noop",working:"getLocales, getCalendars, useLocales, useCalendars, locale, locales, timezone, isoCurrencyCodes, region, isRTL, isMetric, currency, decimalSeparator, digitGroupingSeparator, getLocalizationAsync, addLocaleListener, addCalendarListener, removeSubscription",missing:"OS-level locale change events (browser limitation; addLocaleListener is a noop)"}]},"expo-local-authentication":{category:"Auth & Payments",stubType:"native",versions:[{range:">=13.0.0",coverage:.85,note:'native-seam: the LocalAuthentication.js wrapper + AuthenticationType/SecurityLevel enums + types run from the real bundle; only the ExpoLocalAuthentication expo module is ours, and it mirrors expo iOS LocalAuthenticationModule.swift exactly for the reference simulator (iPhone 16 Face ID device, no biometrics enrolled, no passcode): hasHardwareAsync true, isEnrolledAsync false, supportedAuthenticationTypesAsync [FACIAL_RECOGNITION], getEnrolledLevelAsync NONE, authenticateAsync resolves {success:false,error:"passcode_not_set"|"not_enrolled"} per disableDeviceFallback \u2014 the exact convertErrorCode path. cancelAuthenticate is deliberately absent so the wrapper faithfully throws UnavailabilityError on iOS (it is @platform android upstream). this IS the complete faithful contract on the reference device, same tier as react-native-exit-app / react-native-orientation-locker: a default iOS Simulator equally cannot run a real biometric prompt.',working:"full ExpoLocalAuthentication native surface with upstream-exact iOS-simulator semantics \u2014 hasHardwareAsync, isEnrolledAsync, supportedAuthenticationTypesAsync, getEnrolledLevelAsync, authenticateAsync (disableDeviceFallback-aware error codes); real package enums/types/wrapper run from the bundle so SecurityLevel.BIOMETRIC alias + UnavailabilityError guards behave exactly as upstream; iOS/android platform divergence (cancelAuthenticate) preserved",missing:"no real biometric prompt can succeed \u2014 but neither can the reference iOS Simulator (no enrolled biometrics, no secure enclave); a real success path would require physical biometric hardware that browsers and simulators alike do not expose"}]},"expo-video":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.7,note:"HTML5 video playback works; player duration/currentTime not synced back from element",working:"VideoView (HTML5 video element), useVideoPlayer/createVideoPlayer hooks, play/pause/seekBy/replay/replace/release/addListener/removeAllListeners, VideoView ref API (enterFullscreen/exitFullscreen/startPictureInPicture/stopPictureInPicture), isPictureInPictureSupported (returns false), VideoAirPlayButton (null noop), clearVideoCacheAsync/setVideoCacheSizeAsync/getCurrentVideoCacheSize",missing:"player.duration stays 0 (no timeupdate listener), player.currentTime not synced from element, statusChange/volumeChange/timeUpdate events not emitted, useEvent hook not exported, DRM support absent"}]},"react-native-date-picker":{category:"UI Components",stubType:"native",versions:[{range:">=5.0.0",coverage:.85,note:"real HTML date / time / datetime-local input backing the picker, plus a real overlay <dialog> for modal/open mode. all core date-flow events (onDateChange / onConfirm / onCancel) wire through native input events. native iOS wheel-spin UX is the documented absent shape.",working:"DatePicker, date, onDateChange, onConfirm, onCancel, mode (date/time/datetime), minimumDate, maximumDate, minuteInterval, modal, open, DatePickerModal",missing:"native iOS wheel-spin visual (browsers default to date-input chrome), full locale formatting (relies on toLocaleString defaults), themed light/dark styling tokens"}]},"react-native-blob-util":{category:"Storage & Data",stubType:"native",versions:[{range:">=0.18.0",coverage:.85,note:"fetch-based HTTP + IndexedDB file storage; binary read/write with base64 supported. fs.ls now enumerates IDB keys honestly, fs.df reports navigator.storage.estimate quotas, fs.readStream/writeStream/slice/lstat fill the rest of upstream's fs surface.",working:"fs.readFile, fs.writeFile (with base64), fs.appendFile, fs.exists, fs.unlink, fs.mkdir (noop \u2014 flat IDB), fs.stat, fs.lstat, fs.cp, fs.mv, fs.slice (byte range copy), fs.hash (Web Crypto SubtleCrypto with sha1/256/384/512; md5 falls back to sha1 with warning shape), fs.isDir (true when any key has the path as strict prefix \u2014 directories are virtual in IDB), fs.ls (honest IDB-key enumeration filtered by path prefix, returns immediate-child basenames), fs.df (navigator.storage.estimate quota / free), fs.readStream (queues a single onData chunk in encoded form, then onEnd; respects bufferSize chunking for utf8 strings), fs.writeStream (in-memory accumulator flushed on close; honors utf8/ascii/base64 encodings), dirs constants, fetch (via ReactNativeBlobUtil.fetch), config().fetch with fileCache/path, wrap, base64.encode/decode, session (noop shape), polyfill",missing:"real chunked progress events on fetch (browsers don't expose per-chunk fetch progress), net namespace (Android Download Manager has no browser equivalent), Android-specific options (trusty, wifiOnly \u2014 no parallel on web)"}]},"react-native-haptic-feedback":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.9,note:"package-local wrapper registers only the RNHapticFeedback TurboModule; upstream react-native-haptic-feedback JS runs unchanged against the browser vibration API where available. full upstream API surface \u2014 every documented entry point lands on either real navigator.vibrate work or correct unavailable shape.",working:"sootsim validated upstream trigger, stop, isSupported, triggerPattern, getSystemHapticStatus, setEnabled, isEnabled, impact, HapticFeedbackTypes, Patterns, pattern/PATTERN_CHARS, and TouchableHaptic; RNHapticFeedback TurboModule uses navigator.vibrate for trigger/triggerPattern/stop and reports browser support shape",missing:"actual Core Haptics/UIKit haptic engine, AHAP file playback, hardware-specific intensity/sharpness rendering \u2014 these are unavailable on web (browser vibration API only honors duration patterns); apps that gate on isSupported take the no-haptic branch correctly"}]},"react-native-get-random-values":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"side-effect polyfill \u2014 browser already has crypto.getRandomValues, noop is correct",working:"polyfills globalThis.crypto.getRandomValues if absent (Math.random fallback)"}]},"react-native-securerandom":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"native RNSecureRandom seam backed by Web Crypto random bytes",working:"upstream generateSecureRandom(length) runs unchanged; RNSecureRandom.generateSecureRandomAsBase64(length) returns cryptographically secure base64 bytes"}]},"react-native-randombytes":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:1,note:"native RNRandomBytes seam backed by Web Crypto random bytes",working:"upstream randomBytes(length), randomBytes(length, callback), seedSJCL, and seed initialization run unchanged; RNRandomBytes.seed and RNRandomBytes.randomBytes(length, callback) return base64 secure random bytes"}]},"@react-native-google-signin/google-signin":{category:"Auth & Payments",stubType:"native",versions:[{range:">=10.0.0",coverage:.55,note:"package-local RNGoogleSignin TurboModule seam; upstream JS runs unchanged for signed-out iOS flows, with RN oracle documenting the upstream new-arch provider gap",working:"upstream GoogleSignin, GoogleSigninButton, statusCodes, and helper predicates run unchanged; configure, hasPlayServices, hasPreviousSignIn, getCurrentUser, addScopes, signInSilently no-saved response, getTokens signed-out rejection, clearCachedAccessToken, signOut/revokeAccess, and codegen native button press render through the RNGoogleSignin seam",missing:"real Google OAuth popup/redirect flow, token exchange, keychain-backed current user persistence, successful scope grants, One Tap / web credential support, and upstream iOS new-arch module provider registration in the RN oracle app"}]},"@invertase/react-native-apple-authentication":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.4,note:'performRequest returns deterministic simulated credentials \u2014 a fake JWT-shaped `identityToken` and `authorizationCode` that look real but fail any downstream Apple-public-key verification. consumer code that ships its own token verifier (which is the recommended SIWA pattern) hits a confusing "invalid signature" error rather than the unavailable-on-web branch. expo-apple-authentication dropped to 0.2 (PR #38) for the same pattern \u2014 this one is slightly higher only because the AppleButton component + enums + Android WebView signIn shape are still present.',working:"AppleButton component with upstream string Style/Type constants, appleAuth support flags, Error/Operation/Scope/State/UserStatus aliases, performRequest validation, getCredentialStateForUser, credential revoke listeners, appleAuthAndroid configure/signIn/Scope/ResponseType/Error",missing:"real Sign-in-with-Apple OAuth flow via AppleID JS SDK (Service ID + HTTPS); real Apple-signed identityToken (current token is a fabricated JWT that fails consumer-side signature verification against Apple's public keys); real authorizationCode that a backend can exchange; AppleIDProvider availability detection; keychain-backed credential state across reloads; Android WebView OAuth redirect interception; native cancellation/error code propagation"}]},"expo-apple-authentication":{category:"Auth & Payments",stubType:"native",versions:[{range:">=50.0.0",coverage:.2,note:`unavailable-on-web shape per docs/compat-scoring.md ("keep low unless we add a real browser OAuth flow"): enums and button render, isAvailableAsync returns false, signInAsync/refreshAsync/signOutAsync reject with ERR_NOT_AVAILABLE matching how an unavailable native module behaves. Apps with graceful-degradation paths take the right branch. Returning a fake credential here would lie to consumer code that may try to verify the identityToken against Apple's keys.`,working:"isAvailableAsync (false), AppleAuthenticationButton render (sign in / continue / sign up, WHITE/WHITE_OUTLINE/BLACK styles), all enum exports (Scope, Operation, CredentialState, UserDetectionStatus, ButtonType, ButtonStyle), formatFullName, getCredentialStateAsync (NOT_FOUND), addRevokeListener",missing:"real Sign-in-with-Apple OAuth flow (would need AppleID JS SDK + Service ID + HTTPS)"}]},"@stripe/stripe-react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.20.0",coverage:.85,note:"real Stripe.js delegation \u2014 initStripe() lazy-loads https://js.stripe.com/v3/ on first call (no upfront network cost), then every payment op (createPaymentMethod, confirmPayment, confirmSetupIntent, createToken, retrievePaymentIntent / SetupIntent, handleNextAction, verifyMicrodepositsForPayment / Setup) delegates to the real Stripe instance and talks to api.stripe.com over HTTPS. tokenization, payment intents, setup intents, and 3DS are the real implementation; errors are mapped into upstream StripeError shape. <CardField> / <CardForm> / <AuBECSDebitForm> / <PaymentMethodMessagingElement> mount real Stripe Elements iframes (PCI-compliant card collection). Apple Pay / Google Pay route through stripe.paymentRequest (the cross-platform abstraction). native PaymentSheet, CustomerSheet, AddressSheet, AddToWalletButton, and openApplePaySetup remain documented-unavailable (no web equivalents for the native bottom sheets / PassKit setup).",working:"real Stripe.js tokenization + intent flow \u2014 initStripe (loads js.stripe.com/v3 lazily, caches Stripe instance per publishableKey), createPaymentMethod (real), confirmPayment (real, via stripe.confirmCardPayment), confirmSetupIntent (real, via stripe.confirmCardSetup), createToken (real, via stripe.createToken \u2014 bank_account / pii / account; Card requires a mounted CardField), retrievePaymentIntent / retrieveSetupIntent (real), handleNextAction (real, via stripe.handleCardAction), handleNextActionForSetup (real, via stripe.handleNextAction), verifyMicrodepositsForPayment / Setup (real). real Stripe Elements: CardField / CardForm / AuBECSDebitForm / PaymentMethodMessagingElement mount stripe.elements().create(...) DOM iframes when wrapped in a StripeProvider. platform pay paths (confirmPlatformPayPayment / confirmPlatformPaySetupIntent / createPlatformPayPaymentMethod) route through stripe.paymentRequest \u2014 Apple Pay + Google Pay flow through the same browser PaymentRequest sheet Stripe.js abstracts. feature detection: isPlatformPaySupported via window.ApplePaySession.canMakePayments() + window.PaymentRequest. all upstream React surface: StripeProvider, useStripe / usePaymentSheet / usePlatformPay / useConfirmPayment / useConfirmSetupIntent / useApplePay / useGooglePay / useFinancialConnectionsSheet / useOnramp / useCustomerSheet hooks; StripeContainer / AddToWalletButton / AddressSheet / PlatformPayButton / CustomerSheet / ConnectComponentsProvider components; loadConnectAndInitialize, Constants (ApplePayContactFieldsType, ApplePayMerchantCapability, ApplePayShippingType, AndroidGooglePayButtonStyle / Type, IosGooglePayButtonType), all upstream error enums (Confirm/CardAction/Setup/CreatePayment/CreateToken/RetrievePayment/RetrieveSetup/ApplePay/PaymentSheet/Onramp/GooglePay/VerifyMicrodeposits/CollectBankAccount/AddressSheet/CustomerSheet/PlatformPay/Radar), CardBrand enum, PaymentMethodLayout, StripeError + ErrorType + MissingRoutingNumber",missing:'native PaymentSheet UI (the iOS-styled bottom drawer; web has stripe.elements().create("payment") as a primitive but the styled chrome differs). CustomerSheet / AddressSheet UI (no clean web equivalent). AddToWalletButton + openApplePaySetup (PassKit-only operations). createTokenForCVCUpdate (requires a mounted CardCvcElement). collectBankAccount* APIs (require a Financial Connections session token from the merchant server). raw Stripe Connect embedded components (would need @stripe/connect-js dep). when running inside the sootsim tenant worker (no `document`), Stripe.js cannot load \u2014 a future SootSim.bridges.stripe host helper would proxy DOM ops; the stub surfaces a typed error in that case so consumer code branches through error UI.'}]},"@swan-io/react-native-browser":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.1.0",coverage:.55,note:"upstream package JS runs unchanged against RNSwanBrowser native module backed by window.open",working:"TurboModuleRegistry RNSwanBrowser provides open/close, listener bookkeeping, popup URL opening; upstream openBrowser/closeBrowser/processColor/onClose wrapper stays in the app bundle",missing:"real SFSafariViewController/Chrome Custom Tabs UI, native modal transition behavior, Custom Tabs package selection/fallbacks, OS-level user dismissal detection"}]},"@notifee/react-native":{category:"Notifications",stubType:"native",versions:[{range:">=7.0.0",coverage:.15,note:"all noop \u2014 full API surface stubbed with correct shapes, no real notifications fire",working:"all constants (AndroidImportance, AndroidVisibility, EventType, AuthorizationStatus, TriggerType, RepeatFrequency), requestPermission returns AUTHORIZED shape, createChannel returns id, onForegroundEvent returns unsubscribe",missing:"actual notification display, real channel state, badge persistence, power manager info, background event execution, trigger scheduling"}]},"@segment/analytics-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.7,note:"full noop \u2014 createClient returns stub, no destination sends data",working:"createClient, AnalyticsProvider, useAnalytics hook, Plugin/DestinationPlugin base classes, EventType/PluginType/UpdateType enums, getAnonymousId stub",missing:"all event delivery \u2014 track, identify, screen, group, alias, flush silently drop; no HTTP transport; consent/storage APIs not stubbed"}]},"@metamask/react-native-search-api":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.75,note:"iOS Search API wrapper with in-memory Spotlight/app-history state and native event helper surface",working:"default SearchApi instance, spotlight/app-history event listener helpers, indexSpotlightItem(s), delete by identifiers/domains, deleteAll, indexAppHistoryItem",missing:"real CoreSpotlight indexing, NSUserActivity handoff/continueUserActivity delivery from iOS, and public index integration"}]},"expo-keep-awake":{category:"Expo SDK",stubType:"native",versions:[{range:">=14.0.0",coverage:.9,note:"upstream package JS runs against ExpoKeepAwake native-module seam",working:'upstream activateKeepAwake/activateKeepAwakeAsync/deactivateKeepAwake/useKeepAwake/addListener run unchanged; requireNativeModule("ExpoKeepAwake") provides activate, deactivate, isAvailableAsync, addListenerForTag',missing:"actual Screen Wake Lock API acquisition is not held in the canvas worker; isAvailableAsync reflects browser wakeLock support"}]},"react-native-keep-awake":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.75,note:"component lifecycle and static activate/deactivate API match upstream; real idle timer lock requires host wake-lock bridging",working:"default KeepAwake component, static activate, static deactivate, mount activates, final unmount deactivates, render returns null",missing:"actual UIApplication idleTimerDisabled / browser Wake Lock acquisition from the tenant worker"}]},"react-native-version-check":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.4.0",coverage:.8,note:"bundle metadata, store-url builders, provider-based latest-version lookup, and needUpdate version comparison",working:"default export, getCountry, getPackageName, getCurrentBuildNumber, getCurrentVersion, getAppStoreUrl, getPlayStoreUrl, getStoreUrl, getLatestVersion with function/object/appStore/playStore providers, needUpdate",missing:"native app bundle values are simulator defaults; app-store/play-store lookups depend on runtime fetch/CORS and external store availability"}]},"expo-mail-composer":{category:"Device & Platform",stubType:"native",versions:[{range:">=15.0.0",coverage:.85,note:"upstream expo-mail-composer JS runs unchanged; package-local wrapper only registers the ExpoMailComposer native module with clean unavailable simulator state.",working:"isAvailableAsync, getClients, composeAsync, MailComposerStatus enum, and types through upstream MailComposer.ts/MailComposer.types; simulator state reports unavailable with no installed mail clients",missing:"cannot present native MFMailComposeViewController or query installed mail apps from the worker; composeAsync rejects when unavailable, matching iOS simulator behavior"}]},"expo-navigation-bar":{category:"Expo SDK",stubType:"native",versions:[{range:">=4.0.0",coverage:.75,note:"Android-only; tracks requested navigation-bar state and modern component/static API shape",working:"NavigationBar component with setStyle/setHidden statics, set/get background color, set border/position/behavior/translucent, setVisibilityAsync/getVisibilityAsync, visibility listeners, useVisibility, button style APIs",missing:"real Android system-bar mutation, OS contrast enforcement, actual navigation-bar dimensions/insets, emulator-specific behavior"}]},"expo-print":{category:"Expo SDK",stubType:"native",versions:[{range:">=14.0.0",coverage:.6,note:'only `window.print()` is real (printAsync routes through it for browser print dialog). PDF-output APIs are mocked \u2014 printToFileAsync returns a fabricated `uri: "mock://print.pdf"` with empty `base64`, so apps that upload/share/preview the returned URI silently break.',working:"upstream validation and concurrency guard, printAsync (real window.print), printToFileAsync (stable URI/numberOfPages/base64 shape), selectPrinterAsync, Orientation enum",missing:"printToFileAsync produces `mock://print.pdf` + empty base64 instead of real PDF bytes (would need a worker-side PDF encoder); any consumer that uploads the URI, decodes the base64, or feeds it into a share/preview flow gets a non-PDF. native printer selection / AirPrint sheet unavailable in browser."}]},"expo-store-review":{category:"Expo SDK",stubType:"native",versions:[{range:">=8.0.0",coverage:.9,note:"upstream expo-store-review JS runs unchanged; package-local wrapper only registers the ExpoStoreReview native module.",working:"isAvailableAsync returns iOS-simulator available, hasAction/storeUrl computed by upstream JS, requestReview resolves without a browser StoreKit prompt",missing:"real iOS StoreKit review prompt presentation"}]},"expo-system-ui":{category:"Expo SDK",stubType:"native",versions:[{range:">=4.0.0",coverage:.8,note:'full public API present and round-trips cleanly. background color persisted via sessionStorage and mirrored on globalThis.__sootsimSystemBg so a host-side snapshot consumer (or canvaskit-renderer when we wire this path) can read the latest value. tenant runs in a Web Worker so document.body is not the right target \u2014 sootsim renders the visible device area through the host shell. per registry rulebook ("score high when the full public API surface is present and returns the same unavailable/clean state"), the API itself meets the bar; only the visible effect on the device frame is deferred.',working:"setBackgroundColorAsync (persisted across reloads, mirrored to globalThis), getBackgroundColorAsync (round-trip), enforceRootViewBackgroundColor (re-publishes stored color to the globalThis mirror)",missing:"host-side consumer that reads __sootsimSystemBg and applies the color to the device-frame visible area (deferred \u2014 the API and persistence are correct, the visible effect is the wiring gap)"}]},"expo-tracking-transparency":{category:"Expo SDK",stubType:"native",versions:[{range:">=3.0.0",coverage:.9,note:"upstream expo-tracking-transparency JS runs unchanged; package-local wrapper only registers the ExpoTrackingTransparency native module.",working:"getAdvertisingId returns null for the simulator zero IDFA, getTrackingPermissionsAsync reports undetermined, requestTrackingPermissionsAsync resolves denied, isAvailable, PermissionStatus/useTrackingPermissions exports from upstream JS",missing:"real iOS ATT consent sheet and authorized IDFA access"}]},"expo-image-manipulator":{category:"Image",stubType:"native",versions:[{range:">=11.0.0",coverage:.9,note:"real worker-safe implementation via OffscreenCanvas + createImageBitmap + convertToBlob; both legacy manipulateAsync and v12+ class-based ImageManipulator/Context/Image APIs are wired through to actual pixel work. Output bytes are real PNG/JPEG/WEBP, base64 is real, Context chaining produces correct intermediate frames, SaveFormat/FlipType enums match upstream identity. The remaining gap is SharedObject identity (not a functional difference in pixel output) and a slightly different resize algorithm (OffscreenCanvas drawImage with imageSmoothingQuality=high vs. upstream JS Hermite resampler \u2014 outputs match iOS bicubic in practice).",working:"manipulateAsync (resize/rotate/flip/crop/extent + JPEG/PNG/WEBP output + base64), ImageManipulator.manipulate, useImageManipulator hook, Context chaining (resize/rotate/flip/crop/extent/reset/renderAsync/release), Image.saveAsync with quality, FlipType/SaveFormat enums, all type exports",missing:"SharedRef identity across cross-module boundaries (expo-modules-core SharedObject) \u2014 we mirror the public API surface but consumer code that compares ref identity across modules will see different objects"}]},"expo-auth-session":{category:"Auth & Payments",stubType:"works",versions:[{range:">=5.0.0",coverage:.75,note:"pure JS package runs upstream; auth browser callback depends on expo-web-browser support",working:"upstream AuthRequest/AuthSession/useAuthRequest/useAutoDiscovery, makeRedirectUri, discovery fetch, PKCE generation, token exchange/refresh/revoke helpers, provider helpers",missing:"native/web-browser auth-session callback loop is not complete in sootsim; true external app/deep-link return semantics depend on expo-web-browser and expo-linking stubs"}]},"expo-task-manager":{category:"Expo SDK",stubType:"native",versions:[{range:">=11.0.0",coverage:.88,note:"package-local wrapper registers only the ExpoTaskManager native module; upstream expo-task-manager JS runs unchanged. isAvailableAsync returns false on web per upstream's documented unavailable shape (TaskManager.ts:286), so apps with graceful-degradation paths skip background-task registration correctly. SootSim is exactly as capable here as real expo-on-web (full JS surface + the same documented unavailable shape) \u2014 the only gaps are background execution primitives no browser has.",working:"upstream defineTask/isTaskDefined validation, native EVENT_NAME, isAvailableAsync (false on web), isTaskRegisteredAsync, getTaskOptionsAsync, getRegisteredTasksAsync, unregisterTaskAsync, unregisterAllTasksAsync, notifyTaskFinishedAsync, native task execution events",missing:"persistent native EXTaskService storage, app relaunch/headless execution, real task execution while the browser tab is suspended (browsers do not have iOS Background Fetch / Android WorkManager)"}]},"@datadog/mobile-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.95,note:"full noop \u2014 Datadog RUM/Logs/Trace require native agent, no web SDK bridged",missing:"all DdSdkReactNative, DdLogs, DdRum, DdTrace methods present but discard all data; DatadogProvider renders children without initialization"}]},"react-native-in-app-review":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:1,note:"noop \u2014 resolves true; correct since app store reviews don't apply to browser",working:"RequestInAppReview (resolves true), isAvailable (returns true)"}]},"react-native-inappbrowser-reborn":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:.7,note:"opens URLs via window.open; no deep OAuth redirect detection",working:"open, openAuth, close, closeAuth, isAvailable",missing:"no redirect URL interception for openAuth (returns success immediately), no custom toolbar styling, forceCloseOnRedirection ignored"}]},"react-native-restart":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.0.1",coverage:1,note:"tenant-worker calls route through devMenu.reload \u2192 host window.location.reload(); host-thread callers reload directly",working:"restart(), Restart() (both forms exported)"}]},"react-native-vector-icons":{category:"UI Components",stubType:"native",versions:[{range:">=9.0.0",coverage:.92,note:'NOT stubbed \u2014 the real pure-JS package (createIconSet, the named MaterialIcons/FontAwesome/Ionicons/\u2026 exports with their own bundled glyph maps, the Text-based Icon component) runs unmodified from the bundle. sootsim provides only the native parts: all 19 icon TTFs are shipped as engine assets and registered with the CanvasKit font provider under every fontFamily spelling upstream passes (the iOS UIAppFonts native-linking analog), so `<MaterialIcons name="home"/>` renders the real glyph with no `loadFont()` call; the RNVectorIconsManager/RNVectorIconsModule native module backs getImageSource/getImageSourceSync (real OffscreenCanvas glyph rasterisation) and loadFont.',working:"every named export (MaterialIcons, FontAwesome, Ionicons, MaterialCommunityIcons, Feather, AntDesign, Entypo, EvilIcons, Foundation, Octicons, SimpleLineIcons, Zocial, Fontisto, FontAwesome5 brand/regular/solid, FontAwesome6 brand/regular/solid) renders real glyphs via the bundled+registered TTFs; createIconSet / createIconSetFromFontello / createIconSetFromIcoMoon (upstream pure-JS, runs from bundle); Icon.Button; getImageSource / getImageSourceSync (real rasterised glyph via OffscreenCanvas + FontFace); loadFont / loadFontWithFileName; hasIcon / getRawGlyphMap / getFontFamily (upstream)",missing:"FontAwesome 5/6 Pro faces (license-restricted, cannot bundle \u2014 Free brand/regular/solid work); getImageSource returns a worker blob: URL rather than a native file:// path (functionally equivalent for <Image source>); custom-font flows still depend on the consumer registering their own TTF via expo-font/metro asset (handled by those seams)"}]},"react-native-pdf":{category:"UI Components",stubType:"native",versions:[{range:">=6.0.0",coverage:.7,note:`real PDF rendering via browser-native <embed type="application/pdf"> \u2014 uses the browser's built-in PDF viewer (Chromium PDFium / Firefox pdf.js / Safari PDFKit) with full scrolling, zoom, search, and selection UI for free. page prop honored via #page=N URL fragment per PDF Open Parameters spec. ref.setPage(n) and ref.reload() implemented. onLoadComplete fires with numberOfPages=0 (unknown \u2014 embed exposes no load event with metadata). Works for the 95% of consumer code that wants to display a PDF.`,working:"Pdf component with real PDF rendering, source.uri (http/blob/data URIs all work), page prop \u2192 #page=N fragment, ref.setPage/ref.reload imperative API, onLoadComplete/onError lifecycle (microtask ordering), all prop types accepted (scale/horizontal/fitWidth/spacing/password/etc. as documented even though most are non-controllable from outside the embed)",missing:"reliable numberOfPages reporting (browser PDF viewers do not expose page count to surrounding script), onPageChanged firing during user scroll/swipe, onScaleChanged firing during pinch-zoom, password-protected PDF prompt is the browser's default not a custom UI, annotation editing, fitPolicy/fitWidth granular control"}]},"react-native-contacts":{category:"Device & Platform",stubType:"native",versions:[{range:">=7.0.0",coverage:.65,note:"in-memory address book for app contact flows; no real OS contacts access",working:"getAll/getAllWithoutPhotos, getContactById, getContactsByPhoneNumber, getContactsByEmailAddress, getCount, addContact, openContactForm, openExistingContact, viewExistingContact, editExistingContact, updateContact, deleteContact, permission methods",missing:"real contact database access, native contacts UI, thumbnail/photo writing, groups, container routing, platform-specific permission prompts"}]},"react-native-biometrics":{category:"Auth & Payments",stubType:"native",versions:[{range:">=3.0.0",coverage:.05,note:"full class shape but every method returns unavailable/false \u2014 no WebAuthn backing",working:"ReactNativeBiometrics class instantiates, BiometryTypes constants, all method signatures present",missing:"isSensorAvailable always false, createKeys returns empty publicKey, biometricKeysExist always false, createSignature always fails, simplePrompt always fails, deleteKeys noop \u2014 no WebAuthn integration"}]},"react-native-quick-base64":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"browser-native btoa/atob; byte array helpers in JS",working:"btoa, atob, toByteArray, fromByteArray, trimBase64Padding, shim"}]},"react-native-performance":{category:"Analytics",stubType:"native",versions:[{range:">=5.0.0",coverage:.8,note:"real implementation \u2014 delegates to browser performance.now/mark/measure/getEntries APIs",working:"now(), mark(), measure(), getEntries(), getEntriesByName(), getEntriesByType(), clearMarks(), clearMeasures(), PerformanceObserver uses native globalThis.PerformanceObserver",missing:"RN-native startup timing metrics (bundle load, JS thread init), NativePerformance module, onPerformanceEntry callback; observe() falls back to noop if native PerformanceObserver unavailable"}]},"@shopify/react-native-performance":{category:"Analytics",stubType:"native",versions:[{range:">=4.0.0",coverage:.1,note:"full noop \u2014 DisabledStateController always returns Disabled, no metrics recorded",working:"PerformanceProfiler and PerformanceMeasureView render children, all hooks return noop/disabled values, Logger class present, States/LogLevel constants",missing:"actual TTI/render-pass measurement; StateController enabled path; onRenderPassCompleted never fires real data; no native timing events"}]},"@react-native-community/blur":{category:"UI Components",stubType:"native",versions:[{range:">=4.0.0",coverage:.85,note:"CanvasKit backdrop blur approximation with full current BlurType enum",working:"BlurView, VibrancyView, blurType, blurAmount, blurRadius, overlayColor, enabled, autoUpdate, all 22 BlurType values, reducedTransparencyFallbackColor",missing:"native vibrancy behavior, Android downsample/autoupdate semantics, reduced transparency system setting integration"}]},"@sbaiahmed1/react-native-blur":{category:"UI Components",stubType:"native",versions:[{range:">=4.6.1",coverage:.65,note:"simple CanvasKit blur/liquid-glass approximation for latest native component exports",working:"BlurView, VibrancyView, ProgressiveBlurView, LiquidGlassView, LiquidGlassContainer, BlurSwitch, native component export aliases",missing:"true native progressive gradient blur, exact iOS 26 liquid glass behavior, Android QmBlurView behavior, native switch event payload fidelity, reduced transparency system setting integration"}]},"react-native-linear-gradient":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.9,note:"CanvasKit gradient shader via _gradientColors style prop",working:"LinearGradient, colors, start, end, locations, style, children",missing:"useAngle/angle/angleCenter props (accepted but not applied to gradient calculation), animated gradient"}]},"react-native-document-picker":{category:"Storage & Data",stubType:"native",versions:[{range:">=9.0.0",coverage:.85,note:'native browser <input type="file"> for real picking; comprehensive MIME mapping',working:"pick (single and multi), pickSingle, isCancel, isInProgress, releaseSecureAccess, types constants (allFiles/images/audio/pdf/zip/csv/doc/docx/xls/xlsx/ppt/pptx/plainText), mode/presentationStyle accepted",missing:"pickDirectory (returns null, browser support limited), fileCopyUri always null (no actual file copy), copyTo not implemented, video type not in types"}]},"@react-native-documents/picker":{category:"Storage & Data",stubType:"native",versions:[{range:">=10.0.0",coverage:.9,note:'successor document picker backed by browser <input type="file"> plus local-copy helpers',working:"pick (single and multi), pickDirectory cancel shape, saveDocuments echo shape, keepLocalCopy, isKnownType, releaseLongTermAccess, errorCodes/types constants, isCancel/isErrorWithCode",missing:"native iCloud/Drive providers, long-term bookmarks, virtual file conversion, true directory picking"}]},"react-native-exception-handler":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.8,note:"JS exceptions via window.onerror + unhandledrejection; native handler is noop",working:"setJSExceptionHandler (window.onerror + unhandledrejection), getJSExceptionHandler",missing:"setNativeExceptionHandler is logged noop \u2014 no native crash interception possible in browser"}]},"react-native-mixpanel":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"full noop \u2014 Mixpanel class methods all resolve without sending data",working:"init stores token, all method signatures match 1.x API (track, identify, alias, reset, flush, superProperties, timeEvent, optIn/Out), people object with set/setOnce/increment/append/union/deleteUser/trackCharge",missing:"all event delivery to Mixpanel; getDistinctId returns empty string; distinct ID not generated"}]},"mixpanel-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=3.0.0",coverage:.95,note:"development noop \u2014 official Mixpanel SDK API is present and intentionally drops events",working:"Mixpanel constructor/static init, init, identify, alias, track, trackWithGroups, people/group APIs, super properties, opt in/out, distinct/device ids, flush",missing:"native Mixpanel SDK integration, JS fallback network transport, persistence of ids/super properties"}]},"react-native-zip-archive":{category:"Storage & Data",stubType:"native",versions:[{range:">=6.0.0",coverage:.1,note:"all zip/unzip operations are noops \u2014 no browser ZIP impl",working:"API shape present (zip, unzip, unzipAssets, zipWithPassword, subscribe, isPasswordProtected, getUncompressedSize), path constants, subscribe returns removable listener",missing:"zip (noop), unzip (noop), unzipAssets (noop), zipWithPassword (noop), isPasswordProtected always false, getUncompressedSize always 0 \u2014 no actual compression/decompression"}]},"react-native-wheel-pick":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.7,note:"HTML select + date/time input elements; no spinning wheel UX",working:"Picker (with data, selectedValue, onValueChange), DatePicker (with date, minimumDate, maximumDate, onDateChange, mode: date/time/datetime)",missing:"native spinning wheel animation/UX, isLoop behavior, itemStyle rendering, touch-drag gesture"}]},"react-native-splash-screen":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:1,note:"noop show/hide \u2014 correct, no splash screen concept in browser",working:"show, hide"}]},"expo-audio":{category:"Media",stubType:"native",versions:[{range:">=0.1.0",coverage:.9,note:"native-seam only. real expo-audio package runs from the bundle (enums, hooks, prototype patches, RecordingPresets) \u2014 sootsim only stubs the ExpoAudio native module, backing AudioPlayer with html5 <audio> and AudioRecorder with MediaRecorder+getUserMedia via the shared compat/audio html5 driver.",working:"AudioPlayer (play/pause/seek/loop/volume/rate/mute/replace/remove/setPlaybackRate/setAudioSamplingEnabled), AudioRecorder (prepareToRecordAsync/record/pause/stop with real MediaRecorder+getUserMedia, optional AnalyserNode-backed metering), AudioPlaylist (next/previous/skipTo/add/insert/remove), useAudioPlayer, useAudioPlayerStatus, useAudioRecorder, useAudioRecorderState, useAudioPlaylist, useAudioSampler, useEvent-based status, setAudioModeAsync, preload/clearPreloadedSource, RecordingPresets, AudioMode, AudioQuality, IOSOutputFormat, lock-screen-controls no-op, playbackStatusUpdate / recordingStatusUpdate / audioSampleUpdate events",missing:"requestRecordingPermissionsAsync resolves granted without a real permission probe (browsers prompt at first getUserMedia call), AudioStream PCM source is a no-op (no equivalent web stream API), lock-screen controls map to nothing (mediaSession integration deferred \u2014 only one player can own it)"}]},"react-native-code-push":{category:"Analytics",stubType:"native",versions:[{range:">=5.0.0",coverage:0,note:"correct noop \u2014 OTA updates fundamentally inapplicable in browser sim",working:"codePush HOC returns component unchanged (both direct and options-first patterns), sync resolves UP_TO_DATE, checkForUpdate resolves null, all enums exported, notifyAppReady/allowRestart/disallowRestart/clearUpdates resolve",missing:"no OTA delivery to browser sim is expected; coverage 0 because no functionality is expected or possible"}]},"react-native-onesignal":{category:"Notifications",stubType:"native",versions:[{range:">=5.0.0",coverage:.1,note:"pure noop \u2014 all permission checks return false, no events fire, no real SDK init",working:"initialize/login/logout/setConsentGiven/setConsentRequired (log to console), User tag/alias/email/sms add-remove (noop), User.getTags (empty), InAppMessages trigger (log to console), Debug.setLogLevel, LiveActivities.enter/exit, Session outcome methods, event listener registration",missing:"real push permission, actual subscription token/id (always null), opted-in status (always false), real in-app message display, location sharing, push opt-in actually working"}]},"jail-monkey":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:.9,note:"upstream package JS runs against clean simulator NativeModules/TurboModuleRegistry shape",working:"JailMonkey native module is available through NativeModules and TurboModuleRegistry.getEnforcing; isJailBroken/canMockLocation/trustFall/hookDetected/isOnExternalStorage/AdbEnabled return false, async debug/development checks resolve false, rootedDetectionMethods returns empty object",missing:"real jailbreak/root/hook/mock-location detection, Android external-storage/ADB signals, native debug/development-settings inspection"}]},"react-native-appsflyer":{category:"Analytics",stubType:"native",versions:[{range:">=6.0.0",coverage:.95,note:"noop with console.log \u2014 initSdk/logEvent log but send nothing",working:"initSdk returns resolved promise with stub string, logEvent resolved, getAppsFlyerUID callback invoked with stub UID, generateInviteLink callback invoked with stub URL, all event listener registrations return unsubscribe",missing:"real attribution data, deep link events, install conversion data; validateAndTrackInAppPurchase not stubbed; SKAN/ATT handling not real"}]},"react-native-branch":{category:"Analytics",stubType:"native",versions:[{range:">=5.0.0",coverage:.95,note:"noop with console.log \u2014 BranchEvent.logEvent and setIdentity/logout log but send nothing",working:"BranchEvent class with all standard event name constants, createBranchUniversalObject resolves with stub object (generateShortUrl returns stub URL), subscribe returns unsubscribe, getLatestReferringParams/getFirstReferringParams resolve with empty objects",missing:"real deep link attribution, actual short URL generation, real referral params; link schema validation not stubbed"}]},"react-native-adjust":{category:"Analytics",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"full noop \u2014 Adjust.create/trackEvent log to console but send nothing",working:'AdjustConfig/AdjustEvent/AdjustAdRevenue/AdjustThirdPartySharing class shapes, all getter callbacks invoked with stub values (getAdid returns "stub-adid"), isEnabled returns false',missing:"all attribution tracking, real device IDs (getIdfa/getIdfv return empty), subscription tracking, actual SDK initialization; validatePurchase not stubbed"}]},"react-native-fbsdk-next":{category:"Auth & Payments",stubType:"native",versions:[{range:">=12.0.0",coverage:.1,note:"full shape but login is cancelled immediately \u2014 no real Facebook OAuth or Graph API",working:"Settings.setAppID/setClientToken/setGraphAPIVersion/setAutoLogAppEventsEnabled/setAdvertiserIDCollectionEnabled all accept calls, AppEventsLogger.logEvent/logPurchase log to console, all type shapes",missing:"logInWithPermissions always returns isCancelled:true, AccessToken.getCurrentAccessToken always null, Profile.getCurrentProfile always null, ShareDialog/MessageDialog/GameRequestDialog always isCancelled, no real Graph API, initializeSDK is noop"}]},"react-native-push-notification":{category:"Notifications",stubType:"native",versions:[{range:">=8.0.0",coverage:.35,note:"browser Notification API \u2014 local notifications and scheduling actually fire",working:"configure (calls onRegister, requests Notification permission), localNotification (fires real browser Notification), localNotificationSchedule (setTimeout-backed), requestPermissions (real Notification.requestPermission), checkPermissions, cancelLocalNotification/cancelAllLocalNotifications, setApplicationIconBadgeNumber, createChannel/channelExists/channelBlocked/getChannels stubs, Importance/Priority/RepeatType enums",missing:"remote push registration, FCM/APNs integration, getScheduledLocalNotifications (always empty), getDeliveredNotifications (always empty), real badge read-back, subscribeToTopic/unsubscribeFromTopic (noop), repeat scheduling"}]},"react-native-background-timer":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.85,note:"real browser setInterval/setTimeout; no actual background execution (browser limit)",working:"runBackgroundTimer, stopBackgroundTimer, start, stop, setTimeout, clearTimeout, setInterval, clearInterval",missing:"background execution not possible in browser \u2014 timers pause when tab is hidden (inherent platform limit)"}]},expo:{category:"Expo SDK",stubType:"native",versions:[{range:">=49.0.0",coverage:.8,note:"upstream Expo JS runs; native bridge resolves through expo-modules-core stubs",working:"upstream Expo.ts/Expo.fx/registerRootComponent/useEvent/useEventListener, expo/virtual/env, expo/virtual/rsc, Expo Go detection, expo-modules-core re-exports",missing:"native Expo Go module is absent, full winter runtime/native fetch is not installed, async bundle loading is mapped to sootsim single-bundle behavior"}]},"expo-modules-core":{category:"Expo SDK",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"core bridge infrastructure with explicit native-module registry",working:"EventEmitter, NativeModule, LegacyEventEmitter, NativeModulesProxy, registerWebModule, requireNativeModule, requireOptionalNativeModule, requireNativeViewManager, Platform, createPermissionHook, PermissionStatus, CodedError, UnavailabilityError, SharedObject, SharedRef, uuid, useReleasingSharedObject",missing:"reloadAppAsync, useEvent, useEventListener, installOnUIRuntime, complete native-module catalog is still incremental"}]},"react-native-edge-to-edge":{category:"Device & Platform",stubType:"build-only",versions:[{range:">=1.0.0",coverage:1,note:"SystemBars + stack API fully implemented for web (Android-only feature)",working:"SystemBars (component + pushStackEntry/popStackEntry/replaceStackEntry/setStyle/setHidden), NavigationBar, StatusBar"}]},"react-native-image-crop-picker":{category:"Image",stubType:"native",versions:[{range:">=0.40.0",coverage:.7,note:"real browser file-input picker; cropping is a no-op passthrough",working:"openPicker (single/multiple, mediaType filter, base64, maxFiles), openCamera (with capture attribute), clean, cleanSingle, all Image/Options types",missing:"openCropper does no actual cropping (returns path as-is), compressImageMaxWidth/Height/Quality ignored, exif data not populated, freeStyleCropEnabled/cropperCircleOverlay have no effect"}]},"react-native-orientation-locker":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"all lock/unlock are noops \u2014 orientation cannot be forced in browser",working:"lockToPortrait, lockToLandscape, lockToLandscapeLeft/Right, lockToPortraitUpsideDown, lockToAllOrientationsButUpsideDown, unlockAllOrientations, getOrientation (returns PORTRAIT), getAutoRotateState (returns true), all add/remove listener methods, orientation constants",missing:"lockAsync not wired to browser ScreenOrientation API"}]},"@shopify/react-native-skia":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.75,note:"real canvaskit-wasm backing via the engine instance (`globalThis.__sootsimCanvasKit`); declarative <Canvas> snapshots each commit through an offscreen SkSurface and mounts the encoded PNG as a host image. zero second canvaskit bundle.",working:"<Canvas> with offscreen SkSurface paint\u2192PNG\u2192host <Image>, <Path>/<Rect>/<RoundedRect>/<Circle>/<Oval>/<Line>/<Fill>/<Image>/<Text>/<Group> primitives, <LinearGradient>/<RadialGradient>/<SweepGradient>/<ColorShader> paint shaders, <BlurMask>/<Blur>/<Mask>/<Shadow> mask + image filters, <BackdropFilter>/<BackdropBlur>, <DashPathEffect>/<DiscretePathEffect>/<CornerPathEffect>, Skia.Path/Paint/Color/Shader/MaskFilter/ImageFilter/ColorFilter/Font/Typeface/FontMgr factories, Skia.MakeImageFromEncoded, Skia.XYWHRect/LTRBRect/RRectXY/Point/Matrix, useImage (fetches+decodes through canvaskit), useFont (loads typeface from ArrayBuffer / URL), useFonts (matchFamilyStyle), useCanvasRef + ref.makeImageSnapshot, useValue/useDerivedValue/useComputedValue/useValueEffect/useClockValue listener model, BlendMode/StrokeCap/StrokeJoin/FillType/PaintStyle/TileMode/BlurStyle/FontWeight/FontStyle/FontSlant/FontWidth/ClipOp/PathVerb/PathOp/TextAlign/TextDirection enums.",missing:"<RuntimeShader> SkSL compilation+uniform-binding pipeline, <Points>/<TextPath>/<Glyphs>/<ImageSVG>/<Vertices>/<Patch>/<Atlas>/<Picture>/<FitBox>/<Box>/<BoxShadow> (each logs a one-time hint and renders null), <Paint> as a declarative component, useTouchHandler full gesture state machine (we forward a minimal touch handler shape; consumers should use Pressable wrappers for hit-testing), reanimated worklet-driven canvas redraws (`useSharedValueEffect` listens but the redraw still goes through React reconciliation because sootsim reanimated runs on the JS thread today), Skia.ParagraphBuilder full layout (we keep measurement-only semantics matching the previous stub; for pixel-perfect skia paragraphs apps should wait on the upstream JsiSkParagraphBuilder adapter), Skia.SVG.MakeFromString (canvaskit-wasm omits svg parsing in the size-tuned builds we ship), GPU SkSurface backing on offscreen paints (we use software MakeSurface so each Canvas paint runs on cpu \u2014 TODO: register a real engine host element with its own GrDirectContext for paint-only animation)."}]},"@miblanchard/react-native-slider":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.8,note:"alias to @react-native-community/slider stub via re-export",working:"value, minimumValue, maximumValue, step, onValueChange, onSlidingStart, onSlidingComplete, disabled, minimumTrackTintColor",missing:"thumbImage, minimumTrackImage, maximumTrackImage, StepMarker, renderStepNumber, visual track styling beyond accentColor"}]},"expo-contacts":{category:"Expo SDK",stubType:"native",versions:[{range:">=13.0.0",coverage:.8,note:"native-seam: upstream expo-contacts JS runs from the bundle; the seam now seeds the standard Apple sample address book the bare reference iOS Simulator ships (Kate Bell, Daniel Higgins, John Appleseed, Anna Haro, Hank Zakroff, David Taylor \u2014 the long-stable *@mac.com sample set), so getContactsAsync/getContactByIdAsync return the same contacts a real RN app sees on the conformance Simulator instead of an empty list. add/update/remove then mutate that store like CNContactStore.",working:"reference-Simulator default address book seeded (queryable by name/id, sorted/paginated); upstream enums/constants and JS validation, add/update/remove contacts, getContactsAsync/getPagedContactsAsync with query/sort/pagination, getContactByIdAsync, hasContactsAsync, presentFormAsync, presentContactPickerAsync, writeContactToFileAsync data URI, containers/default container, permission functions; validated through real RN and sootsim add/update/query/remove smoke",missing:"contact-change observer (CNContactStoreDidChange) callbacks, real image fetching for contact thumbnails (imageAvailable false), vCard import/export fidelity beyond JSON-as-data-URI, groups membership persistence, limited-access picker semantics, exact field-format parity with a specific live iOS build (names/emails are the stable documented sample set; phone/address formatting may vary by iOS version), no cross-reload persistence"}]},"@bsky.app/react-native-mmkv":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"re-exports react-native-mmkv stub directly \u2014 all MMKV APIs covered via alias",working:"MMKV class, set, getString/Number/Boolean/Buffer, contains, delete, getAllKeys, clearAll, recrypt, trim, size, addOnValueChangedListener (with bsky scoped overload), useMMKVString/Number/Boolean/Object/Storage",missing:"isReadOnly getter, Mode enum (SINGLE_PROCESS/MULTI_PROCESS)"}]},"@bitdrift/react-native":{category:"Analytics",stubType:"native",versions:[{range:">=0.1.0",coverage:.95,note:"full noop \u2014 bitdrift is native crash/log forwarder with no web SDK",missing:"init, log, addField, removeField, identify, track, flush, startSpan, Logger.logInfo/Debug/Warning/Error \u2014 all present as stubs but send no data"}]},"@mattermost/react-native-paste-input":{category:"Keyboard",stubType:"native",versions:[{range:">=0.3.0",coverage:.9,note:"paste-aware TextInput with file detection via clipboard API",working:"PasteInput (default + named), onPaste with file array, onChangeText, value, multiline, numberOfLines, maxLength, editable, autoFocus, secureTextEntry, placeholder, onFocus, onBlur, disableCopyPaste (accepted, no-op), testID",missing:"onKeyPress, onSelectionChange, onContentSizeChange, onChange (accepted but silently dropped \u2014 not wired to DOM events)"}]},"expo-intent-launcher":{category:"Expo SDK",stubType:"native",versions:[{range:">=11.0.0",coverage:.75,note:"upstream expo-intent-launcher JS runs unchanged; iOS unavailable behavior matches its Android-only native module",working:"upstream ActivityAction and ResultCode constants, iOS UnavailabilityError behavior for startActivityAsync/openApplication/getApplicationIconAsync, package-local wrapper that preserves upstream argument validation and public exports",missing:"real Android Activity result lifecycle, package manager icon extraction, Android settings/app intents, browser URL launch fallback intentionally removed to match iOS sootsim parity"}]},"expo-sms":{category:"Expo SDK",stubType:"native",versions:[{range:">=12.0.0",coverage:.85,note:'native-seam: the upstream expo-sms JS (SMS.js wrapper, attachment processing, argument validation, the {result} resolution path) runs unchanged from the bundle; only the ExpoSMS expo module is ours, mirroring ExpoSMSModule.swift on the reference iOS Simulator EXACTLY \u2014 isAvailableAsync returns false because MFMessageComposeViewController.canSendText() is false on the Simulator, and sendSMSAsync throws the verbatim SMSUnavailableException reason "SMS service is not available" (the !canSendText() guard). this IS the complete faithful contract on the reference device: the iOS Simulator genuinely cannot send SMS, so an app calling expo-sms there already gets exactly this. same faithful "the platform/sim cannot do this, and that is correct" tier as react-native-exit-app / expo-local-authentication.',working:'isAvailableAsync (false \u2014 exact MFMessageComposeViewController.canSendText() on the Simulator), sendSMSAsync (rejects with the verbatim SMSUnavailableException reason); real upstream wrapper handles argument validation/attachment processing and would resolve {result:"sent"|"cancelled"|"unknown"} on a device that can send',missing:"no real Messages compose UI can present \u2014 but neither can the reference iOS Simulator (MFMessageComposeViewController.canSendText() is false there); a real send path needs physical SMS capability the Simulator and browser alike do not expose"}]},"expo-video-thumbnails":{category:"Media",stubType:"native",versions:[{range:">=8.0.0",coverage:.72,note:"package-local wrapper registers only the ExpoVideoThumbnails native module; upstream expo-video-thumbnails JS runs unchanged with browser video/canvas thumbnail extraction where available.",working:'real RN + sootsim validated repeated getThumbnailAsync calls, upstream getThumbnailAsync runs unchanged; requireNativeModule("ExpoVideoThumbnails") provides getThumbnail(sourceFilename, options), time seeking, jpeg quality, header fetch, data/cache uri, unique cache uri generation, and width/height result shape',missing:"native AVAsset/MediaMetadataRetriever decode paths, real file-system writes, worker-context video decode dimensions, content:// access, cross-origin videos that browsers cannot decode, exact native error codes"}]},"@mozzius/expo-dynamic-app-icon":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"noop icon switching \u2014 correct for browser, useDynamicAppIcon hook is functional",working:"setAppIcon, getAppIcon, useDynamicAppIcon"}]},"react-native-compressor":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"native-seam: real package JS runs from the bundle; the Compressor TurboModule is browser-backed (canvas raster compression, HTMLVideoElement metadata/thumbnail, fetch upload/download)",working:"Image.compress loads uri/base64 inputs, preserves aspect ratio, resizes/re-encodes jpg/png, returns uri or base64; getImageMetaData/getVideoMetaData report real dimensions+size; createVideoThumbnail captures the first frame; clearCache resolves (composer onClose); Video.compress passes through and drives progress to completion; backgroundUpload/download use fetch",missing:"native cache file paths, EXIF preservation, ph:// assets, native video/audio transcoding, granular byte-level progress events, background execution beyond browser fetch"}]},"react-native-device-attest":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.1.0",coverage:.3,note:"no hardware attestation in browser \u2014 methods return empty/false",working:"isSupported (returns false), attestDevice/assertKey/generateKey return without crashing",missing:"no real attestation or key generation \u2014 empty strings returned for all crypto outputs"}]},"react-native-uitextview":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.9,note:"renders as sootsim-text so canvas engine handles measurement and drawing",working:"UITextView, children, style, selectable (prop accepted), uiTextView (prop accepted), testID, forwardRef",missing:"native UITextView text selection handles, copy/paste menu, selectable text interaction in canvas"}]},"react-native-modal":{category:"Navigation",stubType:"works",versions:[{range:">=11.0.0",coverage:1,note:"pure JS \u2014 uses Animated + View overlay, runs unmodified in sootsim"}]},"react-native-gifted-chat":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS chat UI \u2014 FlatList + TextInput + View/Text, no native code"}]},"react-native-calendars":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS calendar \u2014 View + Text + TouchableOpacity, no native code"}]},"react-native-markdown-display":{category:"UI Components",stubType:"works",versions:[{range:">=7.0.0",coverage:1,note:"pure JS markdown \u2192 RN components (View, Text, Image), no native code"}]},"react-native-toast-message":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS toast overlay \u2014 View + Animated, no native code"}]},"react-native-confirmation-code-field":{category:"UI Components",stubType:"works",versions:[{range:">=7.0.0",coverage:1,note:"pure JS OTP code input \u2014 TextInput cells, no native code"}]},"react-native-dropdown-picker":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:1,note:"pure JS dropdown \u2014 View + ScrollView + TouchableOpacity, no native code"}]},"react-native-country-picker-modal":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS country picker \u2014 FlatList + Modal, no native code"}]},"react-native-step-indicator":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS step UI \u2014 View + Text rendering, no native code"}]},"react-native-collapsible":{category:"Animation",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS over RN Animated API \u2014 runs as-is from bundle"}]},"react-native-animatable":{category:"Animation",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS over RN Animated API \u2014 runs as-is from bundle"}]},"react-native-image-zoom-viewer":{category:"Image",stubType:"works",versions:[{range:">=3.0.0",coverage:1,note:"pure JS (PanResponder + Image) \u2014 works from bundle without a stub"}]},"react-native-progress":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:1,note:"pure JS progress bars \u2014 SVG + Animated, no native code"}]},"react-native-gifted-charts":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:.95,note:"pure JS charts \u2014 composes RN views, Animated, and react-native-svg without native code",working:"BarChart, LineChart, PieChart, PieChartPro, PopulationPyramid, RadarChart, BubbleChart, animated/gradient chart components",missing:"fidelity is bounded by react-native-svg and Animated coverage"}]},"react-native-svg-charts":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:.95,note:"pure JS d3 + react-native-svg charts \u2014 no native module surface",working:"AreaChart, BarChart, LineChart, PieChart, ProgressCircle, StackedAreaChart, StackedBarChart, XAxis, YAxis, Grid, decorators",missing:"fidelity is bounded by react-native-svg coverage and the package is upstream-unmaintained"}]},"react-native-element-dropdown":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS dropdown/multiselect components \u2014 FlatList, Modal, TextInput, Pressable"}]},"react-native-paper-dates":{category:"UI Components",stubType:"works",versions:[{range:">=0.20.0",coverage:1,note:"pure JS date picker UI built on react-native-paper and date-fns"}]},"react-native-qrcode-svg":{category:"Image",stubType:"works",versions:[{range:">=6.0.0",coverage:1,note:"pure JS QR generator using react-native-svg \u2014 works end-to-end via sootsim SVG engine"}]},"@segment/sovran-react-native":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"JS store runs unmodified; optional native bridge is absent and upstream already degrades to a warning",working:"createStore, dispatch/getState/subscribe queue, registerBridgeStore, AsyncStorage persistor through async-storage stub",missing:"native-to-JS store action bridge events from Sovran native module"}]},"react-native-swiper":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS ScrollView-based carousel \u2014 runs as-is from bundle",working:"Swiper carousel, ScrollView-based paging, dot indicators, autoplay, all standard props"}]},moti:{category:"Animation",stubType:"works",versions:[{range:">=0.20.0",coverage:.7,note:"pure JS, runs from bundle as-is; coverage bound by reanimated stub (0.8)",working:"MotiView, MotiText, MotiImage, MotiScrollView, MotiSafeAreaView, motify, useAnimationState, useDynamicAnimation, AnimatePresence, MotiProgressBar, interactions/skeleton/svg subpaths",missing:"enter/exit layout animations (blocked by reanimated stub gap), useAnimatedSensor-driven animations, any animation requiring real UI-thread worklet execution"}]},"@legendapp/list":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=1.0.0",coverage:.8,note:"pure JS list composing flash-list (which renders as FlatList equivalent in sootsim)",working:"all list rendering via flash-list stub (FlatList equivalent), full Legend list API delegated to flash-list",missing:"inherits flash-list virtualization gap (no native recycling)"}]},"@floating-ui/react-native":{category:"UI Components",stubType:"works",versions:[{range:">=0.10.0",coverage:1,note:"pure JS positioning library \u2014 uses RN layout, no native code"}]},"react-native-switch":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS toggle \u2014 Animated + View, no native code"}]},"@gorhom/portal":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS React-context portal \u2014 runs as-is from bundle, no native modules",working:"Portal, PortalHost, PortalProvider, usePortal, enableLogging"}]},"react-native-render-html":{category:"UI Components",stubType:"works",versions:[{range:">=6.0.0",coverage:1,note:"pure JS HTML to RN components via View/Text/Image, no native code"}]},solito:{category:"Navigation",stubType:"works",versions:[{range:">=4.0.0",coverage:1,note:"pure JS navigation abstraction \u2014 useRouter/useLink delegate to expo-router or react-navigation"}]},"react-native-paper":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:.8,note:"pure JS Material Design \u2014 uses RN primitives + reanimated + svg + safe-area (all stubbed)",missing:"components depending on react-native-svg (Charts, ProgressBar arc), reanimated-driven animations, native ripple effects"}]},"expo-build-properties":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=0.1.0",coverage:1,note:"config-plugin only; no runtime JS API \u2014 no stub needed"}]},"expo-dev-client":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=1.0.0",coverage:.6,note:"config/dev tooling package; isDevelopmentBuild correctly returns false",working:"isDevelopmentBuild"}]},"react-native-drawer-layout":{category:"Navigation",stubType:"works",versions:[{range:">=3.0.0",coverage:.9,note:"pure JS drawer \u2014 runs unmodified, depends on reanimated + gesture-handler",working:"Drawer, DrawerLayout, drawerPosition, drawerType, swipe gestures, open/close callbacks, renderDrawerContent",missing:"gesture fidelity depends on gesture-handler stub completeness"}]},"react-native-tab-view":{category:"Navigation",stubType:"works",versions:[{range:">=3.0.0",coverage:.9,note:"pure JS \u2014 uses ScrollView-based tab pager, runs unmodified",working:"TabView, SceneMap, TabBar, TabBarItem, renderTabBar, initialLayout, lazy, onIndexChange, onTabPress, swipeEnabled",missing:"swipe fidelity depends on gesture-handler/reanimated stub completeness"}]},"react-native-screen-transitions":{category:"Navigation",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"SharedElement passthrough; transition animations not implemented",working:"SharedElement (forwardRef passthrough), createSharedElementStackNavigator (returns navigator as-is), SharedElementTransition (renders null), useSharedElementTransition (returns static {progress:0, closing:0})",missing:"createNativeStackNavigator (intentionally omitted to avoid duplicate nav context), actual shared element animation execution, progress tracking during navigation, element measurement/capture"}]},"@react-native-vector-icons/fontawesome6-pro":{category:"UI Components",stubType:"works",versions:[{range:">=12.0.0",coverage:1,note:"pure JS glyph maps + font files; no native module needed in RN 0.73+"}]},"react-native-draggable-flatlist":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=3.0.0",coverage:.95,note:"pure JS \u2014 composes gesture-handler + reanimated (both stubbed in sootsim)",working:"DraggableFlatList drag-and-drop gesture handling via gesture-handler + reanimated stubs",missing:"fidelity bound by reanimated layout-animation gap"}]},"react-native-email-link":{category:"Device & Platform",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS \u2014 uses Linking API for mailto: URIs, no stub needed"}]},"react-native-logs":{category:"Device & Platform",stubType:"works",versions:[{range:">=5.0.0",coverage:1,note:"pure JS console wrapper \u2014 runs without a stub"}]},"react-native-select-dropdown":{category:"UI Components",stubType:"works",versions:[{range:">=3.0.0",coverage:1,note:"pure JS \u2014 FlatList + TextInput + Modal, no native code"}]},"react-native-size-matters":{category:"UI Components",stubType:"works",versions:[{range:">=0.3.0",coverage:1,note:"pure JS Dimensions scaling utilities, no native code"}]},"@react-native-community/checkbox":{category:"UI Components",stubType:"native",versions:[{range:">=0.5.0",coverage:1,note:"HTML checkbox input with accentColor tinting",working:"CheckBox, value, onValueChange, disabled, tintColors (true/false), testID"}]},"@react-native-segmented-control/segmented-control":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.75,note:"iOS RNCSegmentedControl-compatible component with native event payloads and selected segment styling",working:"default forwardRef component, values, selectedIndex, enabled, momentary, tintColor, backgroundColor, fontStyle, activeFontStyle, testIDS, onChange nativeEvent, onValueChange",missing:"actual UISegmentedControl native drawing, native image segment rendering, processColor numeric conversion, macOS support, exact iOS separator/thumb animation behavior"}]},"@bam.tech/react-native-image-resizer":{category:"Image",stubType:"native",versions:[{range:">=3.0.0",coverage:.75,note:"createResizedImage backed by browser image decoding and canvas resizing",working:"default createResizedImage export, PNG/JPEG/WEBP format mapping, contain/cover/stretch sizing, onlyScaleDown, 90-degree rotation, outputPath/name/path response fields, blob/data URI output and size when canvas APIs are available",missing:"native filesystem persistence, EXIF metadata preservation for keepMeta, exact RCTImageLoader asset resolution, platform-specific WEBP availability differences"}]},"react-native-create-thumbnail":{category:"Media",stubType:"native",versions:[{range:">=2.2.0",coverage:.55,note:"thumbnail creation API with cache-shaped responses and a browser video/canvas extraction path",working:"default create/createThumbnail surface, named createThumbnail/create exports, url/timeStamp/format/cacheName/maxWidth/maxHeight/headers options, cache-name reuse, image/jpeg and image/png response metadata, browser video frame capture when DOM video/canvas APIs can decode the source",missing:"native cache file persistence, AVAssetImageGenerator exact frame selection and time tolerance, Android onlySyncedFrames behavior, cache directory size cleanup, non-DOM worker video decode"}]},"expo-background-task":{category:"Expo SDK",stubType:"native",versions:[{range:">=55.0.0",coverage:.85,note:`native-seam: upstream expo-background-task JS (BackgroundTaskStatus/Result enums, task-name validation, the Restricted-status iOS-Simulator warning path) runs unchanged from the bundle; only the ExpoBackgroundTask expo module is ours, mirroring BackgroundTaskScheduler.swift/BackgroundTaskModule.swift on the reference iOS Simulator EXACTLY \u2014 getStatusAsync returns Restricted (the upstream "if we're on emulator we should definitely return restricted" path) and register/unregisterTaskAsync throw the verbatim simulator exception ("Background Task is not available on simulators. Use a device to test it."). this IS the complete faithful contract on the reference device: BGTaskScheduler does not run on the iOS Simulator at all, so an app calling expo-background-task there already gets exactly this (the upstream JS even has a dedicated Simulator-restricted warning branch). same faithful "the Simulator genuinely cannot do this, and that is correct" tier as expo-sms / react-native-exit-app.`,working:"getStatusAsync (Restricted \u2014 exact upstream emulator path), registerTaskAsync/unregisterTaskAsync (throw the verbatim upstream simulator exception), triggerTaskWorkerForTestingAsync (void), onTasksExpired listener support; upstream enums + task-name validation + the Restricted-status warning path run from the bundle",missing:'real OS background execution windows (BGTaskScheduler/WorkManager) and physical-device "available" status \u2014 but these never work on the reference iOS Simulator either (it reports Restricted by design); a real execution path needs a physical device the Simulator and browser alike do not provide'}]},"expo-background-fetch":{category:"Expo SDK",stubType:"native",versions:[{range:">=13.0.0",coverage:.68,note:"package-local wrapper registers only ExpoBackgroundFetch and ExpoTaskManager native modules; upstream expo-background-fetch JS runs unchanged.",working:"upstream deprecation warning, task-name validation, BackgroundFetchStatus/Result enums, native getStatusAsync, setMinimumIntervalAsync, registerTaskAsync, unregisterTaskAsync, and TaskManager integration",missing:"real suspended-app background execution, Info.plist-driven disabled-mode rejection, BackgroundFetchTaskConsumer scheduling, and physical-device background refresh status changes"}]},"expo-speech-recognition":{category:"Expo SDK",stubType:"native",versions:[{range:">=3.1.0",coverage:.65,note:"ExpoSpeechRecognition module and Web Speech wrapper backed by browser SpeechRecognition when available",working:"ExpoSpeechRecognitionModule start/stop/abort/state, native event addListener/remove, granted permission helpers, recognition availability, speech services/default-service helpers, supported locales, iOS audio-session getters/setters, ExpoWebSpeechRecognition class, grammar/list classes, constants",missing:"native SFSpeechRecognizer and Android SpeechRecognizer engines, real microphone permission prompts, audioSource transcription, recording persistence, locale installation data, offline model downloads, volume metering"}]},"expo-insights":{category:"Analytics",stubType:"native",versions:[{range:">=55.0.0",coverage:.95,note:"package-local wrapper registers only the ExpoInsights native module; upstream public JS is an empty default export.",working:"default export is the upstream empty object; ExpoInsights native module name resolves after importing expo-insights so inlined expo-modules-core bundles do not fall through to the permissive proxy",missing:"native lifecycle telemetry delivery to i.expo.dev is intentionally absent in sootsim"}]},"react-native-aes-crypto":{category:"Device & Platform",stubType:"native",versions:[{range:">=3.0.0",coverage:1,note:"fully backed by Web Crypto API (AES-CBC/GCM, PBKDF2, SHA, HMAC, random)",working:"pbkdf2, sha1, sha256, sha512, hmac256, hmac512, randomKey, randomUuid, encrypt, decrypt"}]},"react-native-amplitude-analytics":{category:"Analytics",stubType:"native",versions:[{range:">=0.2.0",coverage:.1,note:"full noop singleton \u2014 Amplitude.getInstance() works but all methods discard data",working:"singleton via getInstance(), initialize/logEvent/setUserId/setUserProperties/logRevenue method signatures present",missing:"all event delivery; logEventWithTimestamp, setGroup, setOptOut, trackingSessionEvents all noop"}]},"react-native-app-auth":{category:"Auth & Payments",stubType:"native",versions:[{range:">=6.0.0",coverage:.65,note:"real OAuth popup + PKCE + fetch-based token refresh/revoke",working:"authorize() opens popup with PKCE S256, refresh() POSTs to token endpoint, revoke() POSTs to revocation endpoint, register() dynamic client registration, prefetchConfiguration(), logout() redirects",missing:"popup cross-origin redirect interception can fail (CORS), no OIDC metadata auto-discovery fallback, logout uses window.location (navigates away), nonce support missing from authorize params"}]},"react-native-auth0":{category:"Auth & Payments",stubType:"native",versions:[{range:">=5.0.0",coverage:.55,note:"upstream Auth0 JS facade runs unchanged against A0Auth0 TurboModule seam",working:"A0Auth0 native module provides initialize/hasValidInstance, webAuth/logout/cancel/resume, credential save/get/hasValid/clear, API credentials, SSO credentials, DPoP headers, customTokenExchange; upstream Auth0 class/hooks/orchestrators stay in the app bundle",missing:"real hosted-login callback interception, secure Keychain/EncryptedSharedPreferences, biometrics, network refresh-token renewal, Management API persistence, real DPoP signing key material"}]},"@expensify/react-native-live-markdown":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.4,note:"TextInput fallback only \u2014 no actual markdown rendering or syntax highlighting",working:"MarkdownTextInput (plain input), parseExpensiMark (returns []), getWorkletRuntime (returns {})",missing:"actual markdown syntax coloring, formatSelection behavior, worklet-driven inline styling, cursor-aware formatting"}]},"react-native-nitro-cookies":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"document.cookie backed; get/set/remove/clearAll fully functional in browser",working:"get, getAll, set (with path/domain/expires/secure options), remove (with path/domain options), clearAll, Cookie interface",missing:"httpOnly attribute (not settable via document.cookie by design), SameSite option, URL-scoped cookie reading (always reads all document.cookie)"}]},"react-native-nitro-modules":{category:"Essentials",stubType:"native",versions:[{range:">=0.30.0",coverage:.3,note:"proxy framework \u2014 modules using nitro keep loading, but no native bindings actually run",working:"NitroModules.createHybridObject returns chainable proxy (no crash), getHostObject returns same proxy, HybridObject type export, proxy toString/toPrimitive",missing:"NitroModules.hasHybridObject always false, all real native JSI bindings (every call is a noop proxy \u2014 no actual native module functionality)"}]},"react-native-nitro-sqlite":{category:"Storage & Data",stubType:"native",versions:[{range:">=9.0.0",coverage:.85,note:"adapts the shared bedrock-sqlite backend to Nitro's connection-oriented API. real SQL engine inherited from op-sqlite via the shared backend; error wrapping included.",working:"open, execute/Async, executeBatch/Async, transaction (auto commit/rollback against real BEGIN/COMMIT/ROLLBACK), NitroSQLiteError, NITRO_SQLITE_NULL, isNitroSQLiteNull, isSimpleNullHandlingEnabled, enableSimpleNullHandling, NitroSQLite proxy, close, delete, attach, detach, full SQL surface (JOINs, indexes, transactions, RETURNING)",missing:"attach/detach are noops (single-DB in the shared backend), loadFile (noop), update/commit/rollback hooks (bedrock does not expose sqlite3_update_hook through its module surface)"}]},"@op-engineering/op-sqlite":{category:"Storage & Data",stubType:"native",versions:[{range:">=8.0.0",coverage:.9,note:"real SQLite via the shared bedrock-sqlite WASM backend (~1MB, lazy-loaded on first open) with memfs persisted to IDB. full SQL semantics \u2014 joins, transactions, prepared statements, INSERT\u2026RETURNING, PRAGMA. covers Zero / Replicache patterns natively rather than via regex.",working:"open, openRemote, openSync, OPSQLite proxy, DB.execute / executeAsync / executeRaw / executeRawSync / executeBatch / executeBatchAsync, prepareStatement, transaction (real BEGIN/COMMIT/ROLLBACK), close, delete (memfs unlink), getDbPath, attach, detach, Storage class (real CREATE TABLE / INSERT OR REPLACE / SELECT / DELETE), full SQL surface",missing:"updateHook / commitHook / rollbackHook (bedrock has no sqlite3_update_hook binding), reactiveExecute (subscription returns no-op unsubscribe), loadFile (noop), isSQLCipher always false, moveAssetsDatabase noop, sync execute() throws if invoked before bedrock finishes loading \u2014 await executeAsync or whenOpSqliteReady() first"}]},"@ua/react-native-airship":{category:"Notifications",stubType:"native",versions:[{range:">=19.0.0",coverage:.45,note:'native-seam only. real @ua/react-native-airship JS (AirshipRoot, AirshipPush, AirshipContact, AirshipMessageCenter, UAEventEmitter, every public class) runs from the bundle against a load-safe RNAirship TurboModule seam in packages/compat/src/stubs/native-seams/react-native-airship.ts (233 lines, every Spec method). every push/permission API returns a structurally-correct empty value: takeOff resolves false, pushGetNotificationStatus reports unauthorized, contact.getNamedUserId resolves null, addListener/removeAllListeners track in-memory only. matches the per-policy "load-safe noop with no SAAS backend" posture (see registry rulebook).',working:"AirshipRoot constructor + every getter, takeOff, isFlying, push.getNotificationStatus / enableUserNotifications / setForegroundPresentationOptions, contact identify/reset/getNamedUserId, messageCenter list / refresh / dismiss, channel get / addTag / removeTag / setTags, preferenceCenter open, named-user state, iOS.liveActivityManager (every method resolves), addListener / removeAllListeners on UAEventEmitter, all 60+ TurboModule Spec methods accept calls without throwing",missing:"no Urban Airship SAAS backend \u2014 no real push delivery, no remote-config / engage / journey events, no Live Activity binding to ActivityKit, no actual notification permission grant; the seam acknowledges listener registration but never fires events"}]},"react-native-keys":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.7.0",coverage:1,note:"reads keys from SOOTSIM_REACT_NATIVE_KEYS_JSON env or globalThis; URL/token placeholders",working:"KeysTurbo proxy (all public keys), secureFor(name), OSS=true default, injected payload via env/globalThis"}]},"klaviyo-react-native-sdk":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"load-only stub: getConstants returns PROFILE_KEYS / PUSH_TOKEN_VENDOR / EVENT_NAMES so the bundle initializes; calls are no-ops (no real analytics, push, or in-app forms)",working:"KlaviyoReactNativeSdk.getConstants(), Klaviyo namespace + Profile/Push/Forms/DeepLink/Geofencing methods (no-op), ProfileProperty enum"}]},"@welldone-software/why-did-you-render":{category:"Device & Platform",stubType:"native",versions:[{range:">=8.0.0",coverage:1,note:"intentional noop \u2014 wdyr mutates React internals and crashes sootsim's bridged React",working:"default export callable as wdyr(React, opts) without error"}]},"react-native-pure-jwt":{category:"Auth & Payments",stubType:"native",versions:[{range:">=3.0.0",coverage:.9,note:"fully functional via Web Crypto \u2014 sign/verify/decode work with HMAC HS256/384/512",working:"decode() (header+payload parsing), sign() (HMAC via crypto.subtle, HS256/384/512), verify() (signature check + exp validation), base64url encode/decode, iat auto-injection",missing:"RS256/ES256 asymmetric algorithms not supported (Web Crypto could but not implemented), skipValidation option in decode has no effect on signature"}]},"react-native-simple-toast":{category:"UI Components",stubType:"native",versions:[{range:">=3.0.0",coverage:1,note:"DOM toast overlay with gravity (top/center/bottom), duration, and offset",working:"show, showWithGravity, showWithGravityAndOffset, SHORT, LONG, TOP, BOTTOM, CENTER constants"}]},"@react-navigation/native":{category:"Navigation",stubType:"works",versions:[{range:">=6.0.0",coverage:1,note:"pure JS \u2014 NavigationContainer + linking + theming run unmodified on RN primitives",working:"NavigationContainer, useNavigation, useRoute, useFocusEffect, useIsFocused, useNavigationState, CommonActions, StackActions, DefaultTheme, DarkTheme, ThemeProvider, deep linking, state persistence"}]},"@react-navigation/native-stack":{category:"Navigation",stubType:"works",versions:[{range:">=6.0.0",coverage:.9,note:"pure JS wrapper around react-native-screens (stubbed); push/pop, header, modals, large titles all flow through screens stub",working:"createNativeStackNavigator, Screen, Group, Navigator, header config (title, back button, large title, search bar, custom left/right), Android modal/pageSheet push fallback, modal/formSheet/pageSheet presentation, push/pop animations, gesture-driven back, useHeaderHeight",missing:"fidelity bound by react-native-screens stub \u2014 formSheet detent fidelity, search bar placements, freezeOnBlur"}]},"@react-navigation/bottom-tabs":{category:"Navigation",stubType:"works",versions:[{range:">=6.0.0",coverage:.95,note:"pure JS \u2014 tab bar + scene rendering on RN primitives; integrates with screens stub",working:"createBottomTabNavigator, Screen, Navigator, tabBar customization, tabBarIcon/Label/Badge, lazy mounting, useBottomTabBarHeight, BottomTabBarHeightContext, blur tabBarBackground, focus/blur events",missing:"native iOS blur effect on tabBarBackground (uses CSS approximation)"}]},"@react-navigation/stack":{category:"Navigation",stubType:"works",versions:[{range:">=6.0.0",coverage:.9,note:"pure JS \u2014 JS-driven stack navigator with gesture-handler + reanimated for transitions",working:"createStackNavigator, card/modal presentation, gesture-driven back, header animations, TransitionPresets (Slide, Modal, Fade), interpolators, headerStyleInterpolators, custom transitionSpec",missing:"transition fidelity depends on reanimated stub completeness; some advanced TransitionPresets may render without easing details"}]},"@react-navigation/drawer":{category:"Navigation",stubType:"works",versions:[{range:">=6.0.0",coverage:.9,note:"pure JS \u2014 composes react-native-drawer-layout (stubbed) + gesture-handler + reanimated",working:"createDrawerNavigator, drawerType (front/back/slide/permanent), drawerPosition, swipe to open, drawerContent customization, useDrawerStatus, useDrawerProgress",missing:"gesture/animation fidelity bound by drawer-layout + gesture-handler stub completeness"}]},"@react-navigation/material-top-tabs":{category:"Navigation",stubType:"works",versions:[{range:">=6.0.0",coverage:.9,note:"pure JS \u2014 wraps react-native-tab-view (also pure JS), runs unmodified",working:"createMaterialTopTabNavigator, TabBar, scrollable tabs, tabBarIndicator/Label/Icon, swipeEnabled, lazy mounting",missing:"swipe fidelity inherited from gesture-handler/reanimated stubs"}]},"@react-navigation/elements":{category:"Navigation",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS UI primitives shared by all @react-navigation navigators",working:"Header, HeaderBackButton, HeaderTitle, MissingIcon, PlatformPressable, ResourceSavingView, SafeAreaProviderCompat, getDefaultHeaderHeight, getHeaderTitle, useHeaderHeight, Background"}]},"react-native-is-edge-to-edge":{category:"Device & Platform",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure JS helper \u2014 upstream exports constant edge-to-edge true checks and a noop validator",working:"isEdgeToEdge, isEdgeToEdgeFromLibrary, isEdgeToEdgeFromProperty, controlEdgeToEdgeValues"}]},"@react-navigation/routers":{category:"Navigation",stubType:"works",versions:[{range:">=7.0.0",coverage:1,note:"pure JS navigation state machines \u2014 no native modules or views",working:"CommonActions, BaseRouter, DrawerRouter/Actions, StackRouter/Actions, TabRouter/Actions"}]},"@expo/vector-icons":{category:"UI Components",stubType:"works",versions:[{range:">=14.0.0",coverage:.85,note:"pure JS icon components over Text plus expo-font; glyph rendering follows loaded font support",working:"icon family components, createIconSet helpers, Button components, glyph maps, loadFont through expo-font, Text-based glyph rendering",missing:"getImageSource/getImageSourceSync depend on expo-font renderToImageAsync/native vector-icon image APIs and may return null or throw"}]},"@expo/metro-runtime":{category:"Expo SDK",stubType:"works",versions:[{range:">=55.0.0",coverage:.85,note:"JS dev/runtime package \u2014 location, server-log, and rejection tracking install without app native modules",working:"runtime entrypoint, location polyfill install, RSC runtime import, web getDevServer path, development log capture and promise rejection tracking on supported globals",missing:"native reload/logbox paths depend on RN DevSettings and internal native LogBox behavior; production app functionality is unaffected"}]},"@expo/router-server":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=55.0.0",coverage:1,note:"Expo Router server/SSR support package; no tenant native runtime surface"}]},"react-native-url-polyfill":{category:"Essentials",stubType:"works",versions:[{range:">=2.0.0",coverage:.9,note:"pure JS WHATWG URL/URLSearchParams polyfill; NativeModules.BlobModule access is guarded",working:"URL, URLSearchParams, setupURLPolyfill, auto.js web guard, canParse, global URL/URLSearchParams installation",missing:"React Native BlobModule-specific createObjectURL path is absent when BlobModule is unavailable; browser Blob URLs should use the native URL implementation"}]},"react-native-svg-transformer":{category:"Image",stubType:"build-only",versions:[{range:">=1.0.0",coverage:1,note:"Metro transformer only \u2014 converts SVG files through SVGR at build time"}]},"react-native-swipe-gestures":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:.95,note:"pure JS PanResponder wrapper for directional swipe callbacks",working:"GestureRecognizer default export, swipeDirections constants, onSwipe/onSwipeUp/onSwipeDown/onSwipeLeft/onSwipeRight, config thresholds",missing:"fidelity follows the base React Native PanResponder implementation"}]},"react-native-modal-datetime-picker":{category:"UI Components",stubType:"works",versions:[{range:">=17.0.0",coverage:.95,note:"pure JS modal wrapper around @react-native-community/datetimepicker",working:"DateTimePickerModal, iOS modal chrome, confirm/cancel/onHide flow, custom header/buttons/picker hooks, Android wrapper path",missing:"date/time picker fidelity is inherited from @react-native-community/datetimepicker and Modal animation timing"}]},"react-native-uuid":{category:"Device & Platform",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"zero-dependency TypeScript RFC4122 implementation \u2014 no native modules",working:"v1, v3, v4, v5, parse, unparse, validate, version, NIL, DNS, URL, OID, X500"}]},"react-native-keyboard-aware-scroll-view":{category:"Keyboard",stubType:"works",versions:[{range:">=0.9.0",coverage:.85,note:"pure JS keyboard-aware ScrollView/FlatList/SectionList HOC over RN Keyboard and measure APIs",working:"KeyboardAwareScrollView, KeyboardAwareFlatList, KeyboardAwareSectionList, listenable keyboard callbacks, scrollToPosition/scrollToEnd/scrollIntoView helpers",missing:"automatic scroll precision depends on RN Keyboard frame events, UIManager.measureLayout, and TextInput.State fidelity"}]},"react-native-reanimated-carousel":{category:"Animation",stubType:"works",versions:[{range:">=4.0.0",coverage:.8,note:"pure JS carousel built on react-native-reanimated and gesture-handler",working:"Carousel component, Pagination export, renderItem flow, shared-value driven offsets, pan gesture integration, stack/parallax layout calculators",missing:"animation and gesture fidelity inherits reanimated worklet/layout gaps and gesture-handler cross-detector limitations"}]},"@expo/react-native-action-sheet":{category:"UI Components",stubType:"works",versions:[{range:">=4.0.0",coverage:.9,note:"pure JS provider/hook wrapper over RN ActionSheetIOS or a custom RN modal sheet",working:"ActionSheetProvider, connectActionSheet, useActionSheet, showActionSheetWithOptions, custom RN sheet fallback, iOS ActionSheetIOS path through the core RN surface",missing:"native sheet fidelity inherits core ActionSheetIOS and Modal animation differences"}]},"react-native-dotenv":{category:"Essentials",stubType:"build-only",versions:[{range:">=3.0.0",coverage:1,note:"Babel import transformer only \u2014 no runtime React Native API surface"}]},"@tamagui/animations-react-native":{category:"Animation",stubType:"works",versions:[{range:">=1.0.0",coverage:.9,note:"pure JS Tamagui animation driver over React Native Animated",working:"createAnimations, usePresence integration, Animated timing/spring mapping, RN View/Text style animation configs",missing:"fidelity follows the base RN Animated implementation"}]},"@tamagui/animations-moti":{category:"Animation",stubType:"works",versions:[{range:">=1.0.0",coverage:.8,note:"pure JS Tamagui animation driver over react-native-reanimated",working:"createAnimations, shared-value style mapping, timing/spring animation plumbing, presence callbacks",missing:"inherits reanimated worklet/layout animation gaps"}]},"@tamagui/shorthands":{category:"UI Components",stubType:"build-only",versions:[{range:">=1.0.0",coverage:1,note:"static Tamagui shorthand config map \u2014 no native runtime surface"}]},"@tamagui/themes":{category:"UI Components",stubType:"build-only",versions:[{range:">=1.0.0",coverage:1,note:"static Tamagui theme/token data \u2014 no native runtime surface"}]},"@tamagui/config":{category:"UI Components",stubType:"build-only",versions:[{range:">=1.0.0",coverage:1,note:"Tamagui design-system config package consumed at compile/config time"}]},tamagui:{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:.9,note:"pure JS component system over React Native primitives and Tamagui runtime",working:"stacks, text, buttons, inputs, forms, portals, popovers, sheets, tabs, dialogs, theme/token runtime, Anchor via RN Linking",missing:"feature fidelity inherits lower-level RN primitives, gesture/animation drivers, and any app-specific Tamagui compiler assumptions"}]},"react-native-redash":{category:"Animation",stubType:"works",versions:[{range:">=18.0.0",coverage:.8,note:"pure JS utility layer over react-native-reanimated plus SVG path math helpers",working:"math/vector/color/path helpers, transition hooks, ReText, withPause/withBouncing helpers, transform utilities",missing:"inherits reanimated defineAnimation/worklet fidelity gaps"}]},"react-native-picker-select":{category:"UI Components",stubType:"works",versions:[{range:">=9.0.0",coverage:.95,note:"pure JS select wrapper around @react-native-picker/picker and RN Modal/TextInput primitives",working:"RNPickerSelect, items/value selection, placeholder, onValueChange, modal input wrapper, Icon/custom input props",missing:"visual fidelity inherits @react-native-picker/picker and Modal behavior"}]},"react-native-sse":{category:"Storage & Data",stubType:"works",versions:[{range:">=1.0.0",coverage:.95,note:"pure JS EventSource implementation using XMLHttpRequest-style networking",working:"EventSource constructor, addEventListener/removeEventListener, open/message/error events, close, reconnect options, headers/body config",missing:"streaming fidelity depends on the browser/XHR implementation available to the tenant runtime"}]},"react-native-modal-selector":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.95,note:"pure JS selector modal built from RN Modal, FlatList, Touchable, TextInput, and View",working:"ModalSelector component, data sections/options, onChange, selectedKey/initValue, custom option/section rendering, search input",missing:"fidelity follows core Modal, FlatList, and touch handling"}]},"@react-native-community/hooks":{category:"Device & Platform",stubType:"works",versions:[{range:">=3.0.0",coverage:.95,note:"pure JS React hooks over RN Dimensions, AppState, Keyboard, AccessibilityInfo, and NetInfo-style APIs",working:"useAppState, useKeyboard, useDimensions/useWindowDimensions, useAccessibilityInfo, useDeviceOrientation, useBackHandler, useInteractionManager",missing:"hook fidelity follows the underlying core RN event surfaces"}]},"react-native-ratings":{category:"UI Components",stubType:"works",versions:[{range:">=8.0.0",coverage:.9,note:"pure JS rating controls over RN Animated, PanResponder, Image, Text, and TouchableOpacity",working:"Rating, AirbnbRating, TapRating, SwipeRating, custom images, fractions, readonly and callback props",missing:"swipe/animation fidelity follows PanResponder and Animated"}]},"react-native-confetti-cannon":{category:"Animation",stubType:"works",versions:[{range:">=1.5.0",coverage:.9,note:"pure JS confetti particles rendered with RN Animated and View/Image primitives",working:"ConfettiCannon component, autoStart, fadeOut, explosionSpeed/fallSpeed, origin, colors, onAnimationStart/onAnimationEnd",missing:"animation timing fidelity follows RN Animated"}]},"react-native-google-places-autocomplete":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.9,note:"pure JS autocomplete widget over TextInput, FlatList, fetch, qs, debounce, and react-native-uuid",working:"GooglePlacesAutocomplete component, text input/list rendering, debounce, query serialization, nearby/current-place request paths, callbacks",missing:"network results require a real Google Places key and browser fetch access; location shortcut inherits geolocation support"}]},"expo-checkbox":{category:"UI Components",stubType:"works",versions:[{range:">=55.0.0",coverage:.95,note:"pure JS checkbox built from Pressable, Image, StyleSheet, and Platform",working:"Checkbox component, value/onValueChange, color/disabled/style props, checkmark image rendering",missing:"exact platform-native checkbox accessibility traits are approximated by RN Pressable"}]},"react-native-chart-kit":{category:"UI Components",stubType:"works",versions:[{range:">=6.0.0",coverage:.9,note:"pure JS chart components over react-native-svg",working:"LineChart, BarChart, PieChart, ProgressChart, ContributionGraph, StackedBarChart, path/point helpers",missing:"visual fidelity inherits react-native-svg text/path/gradient gaps"}]},"react-native-circular-progress":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:.9,note:"pure JS circular progress components over react-native-svg",working:"AnimatedCircularProgress, CircularProgress, arc rendering, fill/tint/background props, children render prop",missing:"visual fidelity inherits react-native-svg arc/stroke animation gaps"}]},"react-native-parsed-text":{category:"UI Components",stubType:"works",versions:[{range:">=0.0.20",coverage:.95,note:"pure JS Text parser/renderer over React Native Text",working:"ParsedText component, pattern matching, URL/phone/email presets, custom renderText/onPress/style handlers",missing:"text layout and press fidelity follows the core RN Text implementation"}]},"react-native-otp-entry":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:.95,note:"pure JS OTP input built from TextInput, Pressable, View, and hooks",working:"OtpInput component, controlled/uncontrolled code value, focus/blur/clear/setValue refs, paste/backspace handling, secure text entry",missing:"keyboard and TextInput event fidelity follows the core RN implementation"}]},"react-native-skeleton-placeholder":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:.8,note:"pure JS skeleton layout; visual fidelity inherits masked-view and linear-gradient support",working:"SkeletonPlaceholder component, Item tree, border/radius/layout props, speed/direction/background/highlight props",missing:"masking and shimmer fidelity depends on @react-native-masked-view/masked-view, react-native-linear-gradient, and Animated timing"}]},"react-native-snap-carousel":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=3.0.0",coverage:.85,note:"pure JS carousel over ScrollView/FlatList, Animated, and PanResponder",working:"Carousel, Pagination, ParallaxImage, horizontal/vertical layouts, item renderer, snap callbacks",missing:"snap precision, momentum, parallax, and loop timing inherit ScrollView/FlatList/Animated fidelity"}]},"react-native-error-boundary":{category:"Essentials",stubType:"works",versions:[{range:">=3.0.0",coverage:.95,note:"pure JS React error boundary with RN fallback UI",working:"ErrorBoundary component, FallbackComponent/fallbackRender/FallbackComponent prop paths, onError/onReset, resetKeys, useErrorBoundary",missing:"fallback rendering fidelity follows core RN View/Text/Button primitives"}]},"react-native-popover-view":{category:"UI Components",stubType:"works",versions:[{range:">=6.0.0",coverage:.85,note:"pure JS popover over RN Modal, Animated, measure, and touch primitives",working:"Popover component, from/content placement props, arrow/background rendering, show/hide callbacks, adaptive positioning logic",missing:"anchor measurement, Modal layering, and animation fidelity inherit sootsim core RN behavior"}]},"react-native-hyperlink":{category:"UI Components",stubType:"works",versions:[{range:">=0.1.0",coverage:.95,note:"pure JS linkifying Text wrapper using linkify-it/mdurl",working:"Hyperlink component, URL/email/phone detection, linkStyle/linkText, onPress/onLongPress, nested Text traversal",missing:"press and nested text fidelity follows the core RN Text implementation"}]},"react-native-mask-text":{category:"UI Components",stubType:"works",versions:[{range:">=0.15.0",coverage:.95,note:"pure JS masked Text/TextInput helpers",working:"MaskedText, MaskedTextInput, mask/maskType/customMask handling, currency/date/phone/CPF/CNPJ/ZIP helpers",missing:"TextInput editing fidelity follows the core RN implementation"}]},"react-native-image-viewing":{category:"Image",stubType:"works",versions:[{range:">=0.2.0",coverage:.85,note:"pure JS image gallery modal over RN Modal, FlatList, Image, and gestures",working:"ImageViewing component, image paging, header/footer render props, swipe-to-close callbacks, double-tap/zoom plumbing",missing:"gesture, zoom, Modal layering, and image fidelity inherit core RN touch/Image behavior"}]},"react-native-popup-menu":{category:"UI Components",stubType:"works",versions:[{range:">=0.19.0",coverage:.9,note:"pure JS popup menu system over RN Views, touchables, layouts, and BackHandler",working:"MenuProvider, Menu, MenuTrigger, MenuOptions, MenuOption, renderers, context actions, open/close/select flow",missing:"precise option positioning and backdrop behavior depend on measure/layout and touch dispatch fidelity"}]},"react-native-material-textfield":{category:"UI Components",stubType:"works",versions:[{range:">=0.16.0",coverage:.9,note:"pure JS Material text field controls over RN TextInput and Animated",working:"TextField, FilledTextField, OutlinedTextField, labels, affixes, character counter, validation/error props",missing:"floating label animation and TextInput fidelity follow core RN Animated/TextInput"}]},"react-native-root-siblings":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:.8,note:"pure JS sibling overlay manager using React state and AppRegistry wrapping",working:"RootSiblingsManager, RootSiblingParent, RootSiblingPortal, update/destroy lifecycle, setSiblingWrapper",missing:"automatic AppRegistry root wrapping and overlay ordering depend on app entry shape and core AppRegistry capture behavior"}]},"react-native-root-toast":{category:"UI Components",stubType:"works",versions:[{range:">=4.0.0",coverage:.8,note:"pure JS toast manager built on react-native-root-siblings and RN Animated",working:"Toast.show/hide, ToastContainer, duration/position/shadow/animation props, keyboard offset handling",missing:"overlay behavior inherits react-native-root-siblings, Animated, Keyboard, and safe-area fidelity"}]},"react-native-flash-message":{category:"Notifications",stubType:"works",versions:[{range:">=0.4.0",coverage:.85,note:"pure JS flash message/banner component over RN Animated, Dimensions, and touchables",working:"FlashMessage component, showMessage/hideMessage helpers, message queue, icon/title/body rendering, position/duration props",missing:"safe-area/status-bar offsets, animation timing, and gesture dismissal inherit core RN behavior"}]},"react-native-status-bar-height":{category:"Device & Platform",stubType:"works",versions:[{range:">=2.0.0",coverage:.9,note:"pure JS status-bar height helper over Platform and Dimensions",working:"getStatusBarHeight, isIPhoneX, skipAndroid option",missing:"exact model-specific values depend on sootsim Platform/Dimensions device metadata"}]},"react-native-autolink":{category:"UI Components",stubType:"works",versions:[{range:">=4.0.0",coverage:.95,note:"pure JS autolinking Text component using autolinker",working:"Autolink component, URL/email/phone/hashtag/mention matching, custom renderers, linkProps/onPress callbacks",missing:"press and nested text fidelity follows core RN Text behavior"}]},"react-native-section-list-get-item-layout":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure JS getItemLayout calculator for SectionList \u2014 no native runtime surface",working:"section/item/header/footer separator length calculation and SectionList getItemLayout helper generation"}]},"react-native-responsive-screen":{category:"Device & Platform",stubType:"works",versions:[{range:">=1.0.0",coverage:.95,note:"pure JS responsive dimension helpers over RN Dimensions",working:"widthPercentageToDP, heightPercentageToDP, listenOrientationChange, removeOrientationListener",missing:"orientation updates follow core RN Dimensions event fidelity"}]},"react-native-app-intro-slider":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=4.0.0",coverage:.9,note:"pure JS onboarding slider over RN FlatList, Animated, and touchables",working:"AppIntroSlider, renderItem/renderPagination/buttons/dots, next/done/skip callbacks, active index updates",missing:"paging and animation fidelity follows FlatList/Animated behavior"}]},"react-native-controlled-mentions":{category:"UI Components",stubType:"works",versions:[{range:">=3.0.0",coverage:.95,note:"pure JS controlled mentions parser/hooks for RN TextInput",working:"useMentions/useMentionsInput, trigger/part parsing, suggestions state, mention replacement helpers",missing:"selection and editing fidelity follows core RN TextInput behavior"}]},"react-native-responsive-fontsize":{category:"Device & Platform",stubType:"works",versions:[{range:">=0.5.0",coverage:.95,note:"pure JS responsive font-size helpers over RN Dimensions",working:"RFPercentage, RFValue, orientation-aware dimension calculations",missing:"exact values depend on sootsim Dimensions device metrics"}]},"react-native-walkthrough-tooltip":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:.85,note:"pure JS walkthrough tooltip over RN Modal, measure, touchables, and View",working:"Tooltip component, child measurement, placement/topAdjustment/displayInsets, overlay rendering, onOpen/onClose callbacks",missing:"anchor measurement, Modal layering, and touch-through behavior inherit core RN fidelity"}]},"react-native-lightbox-v2":{category:"Image",stubType:"works",versions:[{range:">=0.9.0",coverage:.85,note:"pure JS lightbox overlay over RN Modal, Animated, Dimensions, and Image",working:"Lightbox component, overlay open/close, swipe-to-dismiss, renderHeader/renderContent/renderFooter, pinch/drag plumbing",missing:"gesture, image, Modal, and Animated fidelity inherit core RN behavior"}]},"react-native-lightbox":{category:"Image",stubType:"works",versions:[{range:">=0.8.0",coverage:.85,note:"pure JS legacy lightbox over RN Modal, Animated, Touchable, and Image",working:"Lightbox component, active/inactive child rendering, open/close callbacks, swipe-to-dismiss, custom header/content",missing:"layout measurement, Modal layering, Image, and Animated fidelity inherit core RN behavior"}]},"react-native-ui-datepicker":{category:"UI Components",stubType:"works",versions:[{range:">=3.0.0",coverage:.95,note:"pure JS date picker built from RN views and dayjs/lodash helpers",working:"DateTimePicker component, single/range/multiple modes, calendar navigation, locale/Jalali helpers, style/className props",missing:"touch and text rendering fidelity follows core RN primitives"}]},"react-native-shadow-2":{category:"UI Components",stubType:"works",versions:[{range:">=7.0.0",coverage:.75,note:"source-audited pure JS shadow component; visual proof still needed",working:"Shadow component, distance/startColor/endColor/offset/sides/corners props, SVG gradient shadow rendering",missing:"visual fidelity inherits react-native-svg gradient/path support"}]},"react-native-masked-text":{category:"UI Components",stubType:"works",versions:[{range:">=1.13.0",coverage:.85,note:"pure JS masked TextInput/Text helpers using date-and-time and tinymask",working:"TextInputMask, TextMask, mask types, custom text input, money/date/phone/credit-card/cpf/cnpj/zip helpers",missing:"TextInput selection/editing fidelity follows core RN; bundled vanilla-masker DOM helpers are not part of the RN path"}]},"react-native-shimmer-placeholder":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.8,note:"pure JS shimmer placeholder over Animated and react-native-linear-gradient",working:"ShimmerPlaceholder component/createShimmerPlaceholder, visible toggle, shimmer colors/duration/width/location props",missing:"gradient and shimmer animation fidelity inherits react-native-linear-gradient and Animated behavior"}]},"react-native-qrcode-styled":{category:"UI Components",stubType:"works",versions:[{range:">=0.4.0",coverage:.75,note:"source-audited pure JS QR renderer; visual proof still needed",working:"QRCodeStyled component, data/error correction, logo, piece/eye styling, gradient props",missing:"visual fidelity inherits react-native-svg path/gradient/image support"}]},"react-native-map-link":{category:"Device & Platform",stubType:"works",versions:[{range:">=3.0.0",coverage:.8,note:"pure JS map URL/action builder over RN Linking",working:"showLocation, getApps, openMap, app URL construction, installed-app filtering through canOpenURL",missing:"actual native map app launching is represented by browser/RN Linking behavior in sootsim"}]},"@shopify/restyle":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.95,note:"pure JS styling system over React Native components",working:"createTheme, createBox/createText/createRestyleComponent, composeRestyleFunctions, spacing/color/layout/variant helpers, ThemeProvider/useTheme",missing:"rendered output fidelity follows the underlying RN components"}]},"react-native-awesome-slider":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.8,note:"pure JS slider over react-native-reanimated and gesture-handler",working:"Slider component, min/max/progress shared values, pan/tap gestures, marks/bubble/thumb/render props",missing:"gesture and animation fidelity inherits gesture-handler and reanimated worklet support"}]},"react-native-swipe-list-view":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=3.0.0",coverage:.85,note:"pure JS swipeable list rows over RN FlatList/SectionList, Animated, and PanResponder",working:"SwipeListView, SwipeRow, hidden row rendering, left/right open values, row maps, close/open callbacks",missing:"swipe physics, virtualization, and hidden row layout inherit core Animated/List/PanResponder fidelity"}]},"react-native-modalize":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=2.0.0",coverage:.8,note:"pure JS modal sheet over gesture-handler, Animated, ScrollView/FlatList, and RN Modal",working:"Modalize component, open/close refs, snap points, scrollable content, header/footer, overlay callbacks",missing:"sheet physics, gesture conflict handling, and Modal layering inherit lower-level gesture/Animated/RN fidelity"}]},"react-native-toast-notifications":{category:"Notifications",stubType:"works",versions:[{range:">=3.0.0",coverage:.85,note:"pure JS toast provider/hook over RN Animated and view primitives",working:"ToastProvider, useToast, show/update/hide/hideAll, placement/duration/swipeEnabled/renderType/customToast props",missing:"overlay placement, swipe dismissal, and animation timing inherit core RN behavior"}]},"react-native-collapsible-tab-view":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=8.0.0",coverage:.75,note:"pure JS collapsible tabs over reanimated, pager-view, FlatList/ScrollView, and optional FlashList",working:"Tabs.Container, Tab, MaterialTabBar, FlatList/ScrollView/SectionList/MasonryFlashList wrappers, header/tab interpolation plumbing",missing:"collapsible scroll sync and pager physics inherit reanimated, pager-view, and list virtualization fidelity"}]},"react-native-reanimated-table":{category:"UI Components",stubType:"works",versions:[{range:">=0.0.2",coverage:.9,note:"pure JS table components built from RN views",working:"Table, Row, Rows, Cell, Col, Cols, TableWrapper, border/style/textStyle props",missing:"layout and text fidelity follows core RN View/Text behavior"}]},"react-native-marked":{category:"UI Components",stubType:"works",versions:[{range:">=8.0.0",coverage:.55,note:"source-audited pure JS Markdown renderer; complex output needs conformance proof",working:"Markdown renderer, marked parsing, text/list/link/code/table/image token renderers, custom renderer/theme hooks",missing:"SVG, table layout, links, image rendering, and text nesting fidelity inherit lower-level package support"}]},"react-native-country-flag":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.95,note:"pure JS country flag component rendered as Unicode regional indicators in RN Text",working:"CountryFlag component, isoCode lookup, size/style props",missing:"emoji glyph appearance follows the platform font support in Text"}]},"react-native-bouncy-checkbox":{category:"UI Components",stubType:"works",versions:[{range:">=4.0.0",coverage:.7,note:"source-audited pure JS checkbox component; visual/animation proof still needed",working:"BouncyCheckbox component, checked state, icon/text rendering, fill/unfill colors, bounce/press callbacks",missing:"bounce animation and press fidelity follows core RN Animated/Pressable behavior"}]},"react-native-asset":{category:"Image",stubType:"build-only",versions:[{range:">=2.0.0",coverage:1,note:"asset linking CLI only \u2014 mutates native project files at build time and has no tenant runtime surface"}]},"react-native-level-fs":{category:"Storage & Data",stubType:"works",versions:[{range:">=3.0.0",coverage:.65,note:"source-audited pure JS filesystem facade; storage backend behavior still needs runtime validation",working:"fs-style read/write/stat/readdir helpers backed by LevelUP-compatible storage",missing:"persistence and quota behavior inherit asyncstorage-down and the underlying AsyncStorage implementation"}]},"react-native-phone-number-input":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.65,note:"source-audited pure JS phone input; picker/input UI proof still needed",working:"PhoneInput component, libphonenumber validation/formatting, country picker flow, ref helpers",missing:"country picker modal and TextInput editing fidelity inherit lower-level RN component behavior"}]},"react-native-sortables":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=1.0.0",coverage:.6,note:"source-audited pure JS sortable components; drag/drop proof still needed",working:"Sortable, SortableGrid, SortableFlex, SortableLayer, drag/drop ordering, reanimated layout plumbing",missing:"drag physics inherit reanimated/gesture-handler; optional native haptic adapter only works where RNHapticFeedback is available"}]},"react-native-actions-sheet":{category:"Lists & Sheets",stubType:"works",versions:[{range:">=10.0.0",coverage:.6,note:"source-audited pure JS action sheet; sheet interaction proof still needed",working:"ActionSheet, SheetManager, SheetProvider, router/snap points, scrollable content, keyboard-aware movement",missing:"sheet physics, worklet timing, gesture conflicts, and Modal layering inherit lower-level support"}]},"react-native-network-logger":{category:"Analytics",stubType:"works",versions:[{range:">=2.0.0",coverage:.75,note:"source-audited pure JS development network inspector; runtime interception proof still needed",working:"startNetworkLogging, stopNetworkLogging, getRequests, clearRequests, NetworkLogger component, request detail UI",missing:"coverage depends on the tenant runtime fetch/XHR surfaces and does not observe native networking outside JS"}]},"react-native-geocoding":{category:"Device & Platform",stubType:"works",versions:[{range:">=0.5.0",coverage:.95,note:"pure JS Google Geocoding API client over fetch",working:"init, isInit, from address/latlng/object forms, query serialization, Google response/error handling",missing:"requires a real Google API key and browser fetch access"}]},"react-native-heroicons":{category:"UI Components",stubType:"works",versions:[{range:">=4.0.0",coverage:.75,note:"source-audited pure JS Heroicons components; visual proof still needed",working:"outline/solid/mini/micro icon component exports, size/color/stroke/fill props",missing:"visual fidelity inherits react-native-svg path rendering"}]},"react-native-indicators":{category:"UI Components",stubType:"works",versions:[{range:">=0.17.0",coverage:.65,note:"source-audited pure JS loading indicators; animation proof still needed",working:"BallIndicator, BarIndicator, DotIndicator, MaterialIndicator, PacmanIndicator, PulseIndicator, SkypeIndicator, UIActivityIndicator, WaveIndicator",missing:"animation timing fidelity follows core RN Animated behavior"}]},"react-native-timer-picker":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:.7,note:"source-audited pure JS timer picker; picker UI proof still needed",working:"TimerPicker, TimerPickerModal, hour/minute/second controls, callbacks, modal props, theme/styles",missing:"scroll snapping and Modal fidelity follows core RN behavior"}]},"react-native-autocomplete-dropdown":{category:"UI Components",stubType:"works",versions:[{range:">=5.0.0",coverage:.65,note:"source-audited pure JS autocomplete dropdown; dropdown UI proof still needed",working:"AutocompleteDropdown, controller API, debounce, suggestions list, clear/chevron icons, loading state",missing:"dropdown placement, keyboard behavior, and SVG icon fidelity inherit lower-level RN support"}]},"react-native-phone-input":{category:"UI Components",stubType:"works",versions:[{range:">=1.3.0",coverage:.65,note:"source-audited pure JS phone input; picker/input UI proof still needed",working:"PhoneInput component, country selection, formatting/validation helpers, flag/text customization",missing:"picker modal and TextInput editing fidelity inherit lower-level RN support"}]},"expo-router":{category:"Navigation",stubType:"works",versions:[{range:">=4.0.0",coverage:.85,note:"pure JS file-based router on top of @react-navigation; all routing/loaders/deep linking runs unmodified, three iOS native components are not yet stubbed",working:"Stack, Tabs, Slot, Drawer, Modal, Link, Redirect, useRouter, useLocalSearchParams, useGlobalSearchParams, usePathname, useSegments, useFocusEffect, useNavigation, withLayoutContext, ErrorBoundary, RootHTMLForReactNative, file-based routing, dynamic segments, route groups, typed routes, loaders, deep linking, server-rendered routes (SSR via vxrn)",missing:"<Head> page-title module (iOS-only ExpoHeadModule not stubbed), Link.Preview iOS context-menu preview (LinkPreview native view not stubbed), iOS Toolbar component (RouterToolbarModule not stubbed), native-tabs (UITabBarController-backed Tabs)"}]},"expo-manifests":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=0.13.0",coverage:1,note:"TypeScript types only \u2014 no runtime API surface, importing it is a no-op at runtime"}]},"expo-json-utils":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=0.13.0",coverage:1,note:"native-side helper used internally by expo-updates; JS entry exports null, no runtime API"}]},"expo-structured-headers":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=4.0.0",coverage:1,note:"native-side HTTP-header helper used internally by expo-updates; no JS API surface"}]},"@bacons/apple-targets":{category:"Expo SDK",stubType:"build-only",versions:[{range:">=0.0.0",coverage:1,note:"config plugin that wires extra Xcode targets at build time; no runtime JS API"}]},"@react-native-assets/slider":{category:"UI Components",stubType:"works",versions:[{range:">=11.0.0",coverage:1,note:"pure-JS slider built on PanResponder + Animated \u2014 runs as-is from bundle, no native modules",working:"Slider, RangeSlider, value/minimumValue/maximumValue, step, onValueChange/onSlidingStart/onSlidingComplete, minimum/maximum/thumb tint colors, custom thumb/track components"}]},"react-native-remix-icon":{category:"UI Components",stubType:"works",versions:[{range:">=4.0.0",coverage:1,note:"pure-JS icon set built on react-native-svg \u2014 runs as-is when SVG is supported",working:"RemixIcon component, name/size/color props, full Remix icon catalog rendered through react-native-svg"}]},"react-native-styled-text":{category:"UI Components",stubType:"works",versions:[{range:">=2.0.0",coverage:1,note:"pure-JS Text wrapper that parses inline tags \u2014 runs as-is on base RN Text",working:"StyledText component, inline tag parsing, textStyles prop with named style overrides, nested styled spans"}]},"react-native-datepicker":{category:"UI Components",stubType:"works",versions:[{range:">=1.0.0",coverage:1,note:"pure-JS modal datepicker \u2014 runs as-is from bundle, no native modules",working:"DatePicker component with date/time/datetime modes, format prop, minDate/maxDate, custom styles, open/close imperative API, locale via moment"}]},"@intercom/intercom-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=8.0.0",coverage:.6,note:"load-safe noop \u2014 Intercom singleton + Visibility/LogLevel/ThemeMode enums + IntercomEvents constants; no messenger UI delivered",missing:"no chat UI presentation, no help center fetches return real data, no push token delivery to Intercom servers"}]},"@braze/react-native-sdk":{category:"Analytics",stubType:"native",versions:[{range:">=10.0.0",coverage:.6,note:"load-safe noop \u2014 Braze singleton + ContentCardTypes constants; no event delivery",missing:"no events sent to Braze, content cards always empty, push token not registered, in-app messages not displayed"}]},"@braze/expo-plugin":{category:"Analytics",stubType:"build-only",versions:[{range:">=2.0.0",coverage:1,note:"config plugin that wires Braze into expo prebuild; no runtime JS API"}]},"@bugsnag/react-native":{category:"Analytics",stubType:"native",versions:[{range:">=8.0.0",coverage:.6,note:"load-safe noop \u2014 Bugsnag.start/notify/leaveBreadcrumb/setUser/addMetadata + onError handlers; no error delivery",missing:"no error reports delivered, no breadcrumbs sent, session tracking is a noop, feature flags accepted but not transmitted"}]},"@bugsnag/react-native-performance":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 start/startSpan/startNavigationSpan returning noop spans; no metric delivery",missing:"no spans delivered, no navigation timing recorded, automatic instrumentation absent"}]},"posthog-react-native-session-replay":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 start/startSession/endSession/identify/start-stop-Recording resolve without recording",missing:"no session captures, no canvas recording, isEnabled always false"}]},"customerio-reactnative":{category:"Analytics",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 CustomerIO singleton + Region + CioLogLevel + inAppMessaging/pushMessaging proxies; no event delivery",missing:"no events sent, no profile sync, no in-app messages displayed, push token not registered"}]},"newrelic-react-native-agent":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"load-safe noop \u2014 NewRelic.startAgent + record* methods + interaction tracking; nothing delivered",missing:"no metrics, errors, or events transmitted; interaction IDs are placeholders"}]},appcenter:{category:"Analytics",stubType:"native",versions:[{range:">=4.0.0",coverage:.5,note:"load-safe noop \u2014 AppCenter retired 2025-03-31; setUserId/setEnabled/getInstallId/setLogLevel return placeholder values",missing:"service is end-of-life upstream; no telemetry would land regardless. install id is a fixed placeholder"}]},"appcenter-analytics":{category:"Analytics",stubType:"native",versions:[{range:">=4.0.0",coverage:.95,note:"load-safe noop \u2014 Analytics.trackEvent/trackPageView/setEnabled with no event delivery (AppCenter EOL)",missing:"no events delivered (service is end-of-life)"}]},"appcenter-crashes":{category:"Analytics",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 Crashes.setEnabled/generateTestCrash/notifyUserConfirmation + UserConfirmation constants",missing:"no crash reports delivered (service is end-of-life)"}]},"@fullstory/react-native":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 FullStory singleton with anonymize/event/identify/log/setUserVars/getCurrentSession(URL) accepted; no session-replay recording in browser",missing:"no session video, no rage-tap detection, no DOM mutation feed, no network capture (FullStory native recorder is the only path)"}]},"@iterable/react-native-sdk":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 Iterable singleton + IterableActionSource/InAppShowResponse/InAppCloseSource/LogLevel/EventName constants + inAppManager + embeddedManager namespaces; no messages delivered",missing:"no push registration with Iterable backend, no in-app message fetch, no embedded-message sync, no email/userId persisted server-side"}]},"react-native-google-mobile-ads":{category:"Analytics",stubType:"native",versions:[{range:">=14.0.0",coverage:.7,note:'load-safe noop \u2014 initialize/setRequestConfiguration/AdsConsent flow accepts every call; InterstitialAd / RewardedAd / RewardedInterstitialAd / AppOpenAd / GAM* classes fire onAdFailedToLoad("no-fill") on load() so apps take their no-fill branch; AdEventType / RewardedAdEventType / AdsConsentStatus / BannerAdSize / TestIds constants exposed for type-checked code',missing:"no real ad delivery (Google AdMob requires native SDK + signed-in Google account on device); banner / native-component renders nothing"}]},"react-native-callkeep":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 RNCallKeep.setup/registerPhoneAccount/displayIncomingCall/startCall/endCall and CONSTANTS (END_CALL_REASONS, AUDIO_ROUTE, HANDLE_TYPE) accepted; no CallKit / ConnectionService UI shown",missing:"no CallKit (iOS) / ConnectionService (Android) UI \u2014 browsers have no system-level call screen; getCalls returns empty so apps with active-call UI take the empty branch"}]},"react-native-store-review":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.5.0",coverage:.85,note:"native-seam: the requestReview() wrapper + not-linked guard run from the bundle; the RNStoreReview TurboModule faithfully mirrors the iOS-simulator SKStoreReviewController contract \u2014 requestReview() is a silent void no-op (no prompt on a sim, no throw), exactly the package\u2019s entire one-method Spec. same faithful-unavailable tier as react-native-rate-app / react-native-mail / expo-mail-composer.",working:"requestReview(): void \u2014 matches upstream\u2019s exact single-method Spec; the JS not-linked guard sees a present native module and runs the real path instead of throwing",missing:"no visible in-app rating prompt (the iOS simulator shows none either \u2014 faithful iOS-sim behavior, not a sootsim-specific gap)"}]},"react-native-android-location-enabler":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:'mirrors upstream Android-only constraint \u2014 promptForEnableLocationIfNeeded rejects with a clear "Android-only" error so apps with platform branches take the right path on iOS / web',missing:"no system location-services dialog (Android-specific Settings.Secure flow has no browser equivalent)"}]},"react-native-purchases":{category:"Auth & Payments",stubType:"native",versions:[{range:">=9.0.0",coverage:.45,note:"native-seam only. real react-native-purchases JS (Purchases singleton, CustomerInfo/Offerings parsers, AppUserID generation, listener fan-out) runs from the bundle against a load-safe RNPurchases NativeModule: canMakePayments=false (apps branch on no-IAP), getOfferings returns null/empty, getCustomerInfo returns a stable empty CustomerInfo, purchase* methods reject with PURCHASE_NOT_ALLOWED_ERROR + userCancelled=true. all attribution setters (Adjust/Appsflyer/FB/Firebase/etc.) accept noops so analytics call sites do not throw. pair with react-native-purchases-ui for the full IAP flow.",working:"configure/setup, getCustomerInfo, getOfferings, canMakePayments, isConfigured/isAnonymous, getAppUserID (anonymous), logIn/logOut, restorePurchases, every set* attribution method, addCustomerInfoUpdateListener/removeCustomerInfoUpdateListener, setLogLevel/setDebugLogsEnabled",missing:"no StoreKit / Play Billing \u2014 every purchase* / makeDeferredPurchase rejects, beginRefundRequest* resolves USER_CANCELLED (2), getOfferings is always empty. no real entitlements / receipt validation / paywall UI (pair react-native-purchases-ui for paywall noop)"}]},"react-native-purchases-ui":{category:"Auth & Payments",stubType:"native",versions:[{range:">=8.0.0",coverage:.6,note:'load-safe noop \u2014 RevenueCatUI singleton with presentPaywall/presentPaywallIfNeeded resolving to NOT_PRESENTED (matches upstream "could not display"); PAYWALL_RESULT enum exposed; presentCustomerCenter throws so apps with paywall flows take their offline branch',missing:"no native paywall surface (RevenueCat needs StoreKit/Play to render). pair with react-native-purchases noop for the full IAP flow"}]},"react-native-tcp-socket":{category:"Networking",stubType:"native",versions:[{range:">=6.0.0",coverage:.45,note:'load-safe noop \u2014 Socket / Server / TLSSocket classes plus createServer/createConnection/connect throw a clear "unavailable in browser preview" error so apps with TCP-only paths fail visibly; isIP/isIPv4/isIPv6 helpers return false',missing:"no raw outbound TCP/TLS sockets (browsers only allow WebSocket / fetch); all socket APIs reject"}]},"expo-share-intent":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:1,note:"load-safe noop \u2014 useShareIntent hook reports hasShareIntent=false consistently; ShareIntentProvider passthrough; getShareIntent resolves null. apps with conditional UI on incoming shares take their no-share branch",missing:"no iOS Share Extension / Android ACTION_SEND intent target \u2014 browsers cannot register a system share target. ShareIntentTypes constants exposed for type-checked imports"}]},realm:{category:"Storage & Data",stubType:"native",versions:[{range:">=12.0.0",coverage:.95,note:"load-safe error stub \u2014 Realm class throws on construction, static open/deleteFile reject, schemaVersion=-1, exists=false. apps with realm-required code paths fail visibly; IDB/Zero/Dexie are the right swap on web",missing:"no realm-core in browser. all CRUD ops throw. recommended swap: zero for sync, IDB/Dexie for local-only"}]},"react-native-html-to-pdf":{category:"Storage & Data",stubType:"native",versions:[{range:">=0.12.0",coverage:.45,note:'load-safe error stub \u2014 convert() rejects with a clear "use server-side renderer" error',missing:"no native PDF generation (UIPrintInteractionController / Android PdfDocument have no browser equivalent that returns a base64 file). recommended swap: server-side puppeteer/wkhtmltopdf or jsPDF in-browser"}]},"@kingstinct/react-native-healthkit":{category:"Health",stubType:"native",versions:[{range:">=10.0.0",coverage:.75,note:"load-safe noop \u2014 isHealthDataAvailable=false, authorizationStatusFor=NotDetermined, all queries return empty, save/delete return false. apps with optional HealthKit gated on isHealthDataAvailable take their fallback path",missing:"no HealthKit data store in browser. queries return empty; identifier/unit constants are loose Proxy-based string returns to keep type-checked imports resolving"}]},"react-native-track-player":{category:"Media",stubType:"native",versions:[{range:">=4.0.0",coverage:.7,note:"load-safe noop \u2014 setupPlayer/queue ops/playback controls accepted; getPlaybackState returns State.None; full Event / Capability / RepeatMode / RatingType / IOSCategory enum surface; useTrackPlayerEvents/useProgress/useActiveTrack/usePlaybackState/usePlayWhenReady/useIsPlaying hooks return idle defaults",missing:'no MPMediaPlayer / ExoPlayer integration; no MediaSession / lock-screen controls (browsers have MediaSession but the API surface diverges). State machine stays in None so apps branch on "not playing"'}]},"react-native-windows":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.70.0",coverage:.6,note:"load-safe noop \u2014 Windows-only runtime; exposes a default + Windows namespace so type-checked cross-platform code resolves on iOS/Android/web",missing:"no UWP / WinUI rendering \u2014 Windows-specific APIs throw"}]},"react-native-incall-manager":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 start/stop/setSpeakerphoneOn/setMicrophoneMute/turnScreenOn/turnScreenOff/proximity sensor accepted; chooseAudioRoute resolves a default Speaker route",missing:"no AVAudioSession / AudioManager configuration \u2014 browsers have getUserMedia but no speakerphone toggle, proximity sensor, or audio focus management"}]},"react-native-zeroconf":{category:"Networking",stubType:"native",versions:[{range:">=0.13.0",coverage:.6,note:"load-safe noop \u2014 Zeroconf class with on/off/scan/stop/publishService/getServices accepts every call; no events ever fire so apps with discovery-required UI take their no-services branch",missing:"no mDNS / Bonjour discovery \u2014 browsers have no local network discovery API"}]},"react-native-background-geolocation":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 ready() resolves with enabled=false; configure/start/stop accepted; all on* listeners register but never fire; getProviderState reports gps:false; getCurrentPosition rejects so apps branch on geolocation-unavailable",missing:"no background process \u2014 browsers have no equivalent to the iOS background-fetch / Android foreground service that this SDK schedules. AuthorizationStatus exposed for type-checked code"}]},"react-native-health-connect":{category:"Health",stubType:"native",versions:[{range:">=4.0.0",coverage:.75,note:"load-safe noop \u2014 getSdkStatus reports Unavailable; initialize=false; queries return empty {records, pageToken}; insertRecords returns []. apps with platform branches take their unavailable path",missing:"no Android Health Connect on iOS / web. SdkAvailabilityStatus / PermissionAccess constants exposed for type-checked code"}]},"react-native-capture-protection":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 prevent/allow/preventForCapture/preventForScreenshot/preventForScreenRecord accepted; getPreventStatus reports allow/allow; useCaptureProtection hook returns idle status. apps with screenshot-blocking UI run unaffected",missing:"browsers have no screenshot / screen-recording prevention. CaptureProtectionStatus enum exposed"}]},"react-native-exit-app":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.85,note:'native-seam: the exitApp() wrapper runs from the bundle; the RNExitApp TurboModule is a faithful no-op \u2014 this IS the complete correct contract, not a gap: Apple\u2019s HIG forbids App Store apps from self-terminating and a browser cannot close its tab, so an app calling exitApp() on real iOS already gets nothing user-visible. same faithful "the platform cannot do this, so the no-op is correct" tier as react-native-orientation-locker.',working:"exitApp() \u2014 matches upstream\u2019s exact single-method Spec; faithful complete behavior (no-op, as on real iOS App Store apps)",missing:"none functionally \u2014 the package\u2019s sole purpose (terminate the app) is intentionally unavailable on both iOS App Store apps and browsers; the no-op is the faithful contract, not an unimplemented feature"}]},"react-native-notifications":{category:"Notifications",stubType:"native",versions:[{range:">=5.0.0",coverage:.6,note:"load-safe noop \u2014 Notifications.events() returns subscribers that never fire; registerRemoteNotifications accepts the call without registering; postLocalNotification returns 0; ios/android namespaces accept badge / channel / category ops; isRegisteredForRemoteNotifications=false",missing:"no APNs / FCM token registration; no native notification UI delivered. recommended swap: expo-notifications which sootsim renders through the shell-native UI provider"}]},"@nozbe/watermelondb":{category:"Storage & Data",stubType:"native",versions:[{range:">=0.27.0",coverage:.45,note:'load-safe error stub \u2014 Database constructor throws with a clear "use Zero/Dexie/IDB or LokiJSAdapter on web" suggestion. Model/Collection/Query class exports resolve so type-checked imports compile',missing:"no SQLite adapter on web. WatermelonDB does ship a LokiJSAdapter for web but apps wired to the SQLite adapter need to switch. Q query-builder namespace exposed but inert"}]},"@livekit/react-native":{category:"Networking",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 registerGlobals is a noop; AudioSession namespace accepts startAudioSession/stopAudioSession/configureAudio/selectAudioOutput; setupURLPolyfill noop. recommended swap on web: livekit-client directly",missing:"no native LiveKit RTC bindings \u2014 browsers have WebRTC but lack LiveKit's background-audio + hardware-codec extensions. registerForPushNotifications rejects"}]},"@livekit/react-native-webrtc":{category:"Networking",stubType:"native",versions:[{range:">=125.0.0",coverage:.6,note:"load-safe noop \u2014 registerGlobals/setupReactNativeWebRTC accept calls; on web the global navigator.mediaDevices / RTCPeerConnection are already present so no patching is required",missing:"no native iOS/Android WebRTC bindings. apps that need raw camera capture should use the browser getUserMedia API directly"}]},"expo-iap":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:"load-safe noop \u2014 initConnection=false (apps branch on no-IAP), getProducts/getSubscriptions/getAvailablePurchases return empty arrays, requestPurchase rejects with E_IAP_NOT_AVAILABLE. PurchaseError class + ErrorCode/IAPErrorCode/IapEvent enums exposed for type-checked code",missing:"no StoreKit / Play Billing \u2014 same constraint as react-native-purchases. paywall flows take their offline branch"}]},"react-native-sqlite-storage":{category:"Storage & Data",stubType:"native",versions:[{range:">=6.0.0",coverage:.85,note:"real persistent SQLite via the same lazy-loaded bedrock-sqlite WASM backend as expo-sqlite/op-sqlite/nitro-sqlite \u2014 memfs persists to the tenant-scoped IDB so a reopened database keeps its rows. faithfully mirrors upstream sqlite.js: the default callback style (openDatabase/executeSql/transaction/readTransaction/sqlBatch/close/deleteDatabase) and the enablePromise(true) toggle that swaps every method to promise variants on the same prototypes via the same config table. verified end-to-end against the on-disk bedrock build in the compat suite (callback CRUD + transaction + sqlBatch + close/reopen persistence + promise-mode).",working:"SQLite.openDatabase (object + positional forms), deleteDatabase, enablePromise toggle, DEBUG/getAllDatabases; per-db executeSql (rows.length/item/raw, rowsAffected, insertId), transaction/readTransaction with queued tx.executeSql, sqlBatch, close (handle cached for fast reopen), default `new SQLiteFactory()` export \u2014 all backed by real bedrock SQL (joins, params, RETURNING)",missing:"ATTACH/DETACH across databases (a second memfs open \u2014 parked until a consumer needs it); the slightly broader async/prepared-statement surface that expo-sqlite exposes natively (use expo-sqlite for that)"}]},"@walletconnect/react-native-compat":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"load-safe noop \u2014 this is itself a polyfill package that monkey-patches global objects (Buffer, crypto, async-storage). on sootsim those globals are already wired by our compat layer so importing this is a no-op import; default export is an empty object",missing:"nothing \u2014 its only job (install polyfills) is already done by our base compat layer. flagged as 0.5 because we don't exercise WalletConnect end-to-end yet"}]},"@aws-amplify/react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:'load-safe noop \u2014 runtime helpers (loadGetRandomValues / loadAsyncStorage / loadAppleSignIn) are noops since sootsim already provides those primitives. computeS3Etag returns empty string; getDeviceName returns "sootsim"',missing:"no real AWS SDK calls (Amplify's data-layer talks over fetch/WebSocket which is what runs anyway). flagged 0.5 because no app-side end-to-end coverage yet"}]},"react-native-quick-crypto":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.7.0",coverage:.9,note:"Node crypto surface for React Native bundles; WebCrypto backs random/RSA/subtle, and audited sync primitives back Node-only synchronous hash/HMAC/AES/PBKDF2 contracts.",working:"subtle/webcrypto forwarding, randomBytes/randomFill/randomInt/randomUUID, createHash/createHmac, pbkdf2 callback/promise form, pbkdf2Sync, AES-CBC/GCM/CTR encrypt/decrypt with auth tags, publicEncrypt/privateDecrypt for RSA-OAEP and RSA_PKCS1_PADDING, conversion helpers, constants used by Node crypto consumers",missing:"non-WebCrypto legacy algorithms such as DES/RC4/ChaCha20 are not implemented."}]},"react-native-nitro-crypto":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.3.0",coverage:.9,note:"aliases the WebCrypto-backed react-native-quick-crypto implementation; upstream package is another native Node-crypto surface over Nitro Modules, so the same native crypto contract applies.",working:"same coverage as react-native-quick-crypto: random, sync hash/HMAC, AES-CBC/GCM/CTR, PBKDF2/pbkdf2Sync, RSA-OAEP, RSA PKCS1 v1.5 via the RSA seam, subtle/webcrypto forwarding",missing:"same limitations as react-native-quick-crypto: non-WebCrypto legacy algorithms"}]},"react-native-nitro-totp":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"registers the NitroHotp/NitroTotp/NitroSecret hybrid objects used by upstream JS; HOTP/TOTP are HMAC-backed and secret generation uses secure random Base32.",working:"upstream NitroHotp, NitroTotp, and NitroSecret classes run unchanged through react-native-nitro-modules; SHA1/SHA256/SHA512 HOTP, TOTP currentTime/period/window validation, and compact/standard/extended secret generation",missing:"auth URL generation remains upstream JS; browser preview does not persist generated secrets unless the app stores them"}]},"react-native-rsa-signer":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.9,note:"native RNRsaSigner seam backed by WebCrypto RSASSA-PKCS1-v1_5 SHA-256 key generation and signing.",working:"getPublicKey lazily creates and returns a PEM public key per alias, regenerateKey replaces an alias keypair, sign returns a URL-safe base64 RSA/SHA-256 signature verifiable against the returned public key",missing:"keys are stored in-memory for the tenant runtime rather than OS Keychain/Android Keystore persistence"}]},"react-native-worklets-core":{category:"Animation",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 Worklets.createContext returns a context that runs callbacks on the main JS thread; runOnJS/runOnUI/createWorklet are passthroughs; useRunOnJS/useRunOnUI hooks return the input fn. apps that gate visual work on worklets render correctly without the off-thread benefit",missing:"no off-thread JS execution (matches our react-native-worklets-pkg stub story). complex worklet pipelines that actually need parallelism will see degraded performance, not crashes"}]},"react-native-webrtc":{category:"Networking",stubType:"native",versions:[{range:">=125.0.0",coverage:1,note:"load-safe pass-through \u2014 RTCPeerConnection / RTCIceCandidate / RTCSessionDescription / MediaStream / MediaStreamTrack / mediaDevices forwarded from globalThis (browsers have these natively); registerGlobals is a noop; RTCView component renders null since we have no host-side video bridge yet",missing:"RTCView visual rendering needs a host bridge that paints a video element into the device frame (deferred). raw audio/video peer connections work via the browser globals"}]},"react-native-unistyles":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 UnistylesRuntime exposes plausible iOS portrait defaults (insets matching iPhone safe-area, screen 393x852, fontScale 1, pixelRatio 3); StyleSheet/mq/withUnistyles passthrough; useUnistyles returns a {rt, theme} shape",missing:"no breakpoint-driven rebuilds (browsers can do this via CSS but the unistyles state machine needs JSI hooks). theme switching via setTheme is a noop"}]},"rive-react-native":{category:"Animation",stubType:"native",versions:[{range:">=8.0.0",coverage:.55,note:"load-safe noop \u2014 Rive component renders null (no native renderer in browser); Fit/Alignment/Direction/LoopMode/RiveRenderer enums exposed for type-checked code",missing:"no Rive .riv runtime \u2014 would need shipping the Rive WASM and wiring a canvas (deferred). apps that use Rive for branding/loading animations run cleanly without the visual"}]},"@rive-app/react-native":{category:"Animation",stubType:"native",versions:[{range:">=8.0.0",coverage:.6,note:"identical surface to rive-react-native \u2014 the new official package is just a rename. shares the same noop stub",missing:"same as rive-react-native \u2014 no .riv runtime"}]},"@nandorojo/galeria":{category:"UI Components",stubType:"native",versions:[{range:">=0.5.0",coverage:1,note:"load-safe noop \u2014 Galeria root passes children through; Galeria.Image / Galeria.Popup render null; useGaleria returns no-op { open, close, images: [] }",missing:"no native QLPreviewController \u2014 apps see their gallery layout render but tapping an image does not open the native preview overlay (deferred \u2014 could be wired through host bridge)"}]},"rn-fetch-blob":{category:"Storage & Data",stubType:"native",versions:[{range:">=0.12.0",coverage:.6,note:"alias for react-native-blob-util \u2014 re-exports the same stub which we score at 0.85. flagged here at 0.5 because the older API has callbacks that may differ subtly; consumers should migrate to react-native-blob-util",missing:"same coverage as react-native-blob-util (which scores 0.85)"}]},"expo-gl":{category:"UI Components",stubType:"native",versions:[{range:">=15.0.0",coverage:1,note:'load-safe noop \u2014 GLView component renders null; createContextAsync rejects with "host bridge required" so apps with optional WebGL paths take their fallback',missing:"no WebGL canvas in tenant worker. browsers have WebGL but sootsim renders through CanvasKit on the host \u2014 bridging requires a future host-side GL surface"}]},"@lodev09/react-native-true-sheet":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 TrueSheet component passes children through; present/dismiss/resize/scrollToTop ref methods accepted as noops",missing:"no native bottom-sheet UI. recommended swap on web: a regular sootsim modal \u2014 sootsim already simulates iOS sheet semantics natively"}]},"@stripe/stripe-terminal-react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.0.1",coverage:.75,note:'load-safe noop \u2014 StripeTerminalProvider passthrough; useStripeTerminal returns disconnected state; initialize / discoverReaders / connectReader reject with a clear "hardware unavailable" error. ConnectionStatus / DiscoveryMethod / PaymentStatus enums exposed',missing:"no in-person card reader (BBPOS / WisePOS / Tap to Pay) \u2014 browsers cannot communicate with reader hardware over Bluetooth Classic / Lightning"}]},"react-native-passkey":{category:"Auth & Payments",stubType:"native",versions:[{range:">=3.0.0",coverage:1,note:'isSupported=false (sootsim tenant runs in a worker without DOM); create/get reject with a clear "needs top-level DOM" error so apps with passkey-optional flows take their password fallback. PasskeyError class exposed',missing:"no WebAuthn \u2014 needs DOM access. host iframe could provide this; deferred until host bridge for credential management"}]},"@expensify/react-native-wallet":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 canAddCardToWallet=false / isCardInWallet=false so apps gate Add to Wallet UI off; addCardToWallet rejects",missing:"no PassKit / Google Pay Wallet integration in browser. apps that present the wallet add-card sheet will see the false return and skip the UI"}]},"react-native-udp":{category:"Networking",stubType:"native",versions:[{range:">=4.0.0",coverage:.45,note:"load-safe error stub \u2014 Socket class throws on construction, createSocket throws \u2014 apps with UDP-only paths fail visibly",missing:"no raw UDP API in browser (only WebRTC data channels can do UDP-like, with very different semantics)"}]},"react-native-context-menu-view":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 ContextMenuView passes children through; long-press shows nothing instead of a native UIContextMenu. apps still render their primary content correctly",missing:"no native context menu \u2014 recommended swap on web: a tap-on-icon menu via Pressable + Modal"}]},"expo-quick-actions":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 setItems accepts; getItems returns []; isSupported=false; initial=null; addListener returns a removable subscription that never fires",missing:"no 3D Touch / long-press app-icon shortcuts in browser. apps that gate quick-action UI on isSupported take their fallback path"}]},"react-native-camera-kit":{category:"Media",stubType:"native",versions:[{range:">=14.0.0",coverage:.55,note:"load-safe noop \u2014 Camera component renders null; CameraType / FlashMode / FocusMode / ZoomMode / ResizeMode / ScanBarcodeAlgorithm constants exposed; capture rejects; permission helpers return denied",missing:"no native camera \u2014 recommended swap on web: expo-camera which uses getUserMedia. type-checked imports compile against this stub"}]},"react-native-agora":{category:"Networking",stubType:"native",versions:[{range:">=4.0.0",coverage:.55,note:"load-safe error stub \u2014 RtcEngine throws on construction; createAgoraRtcEngine throws \u2014 apps with Agora-required RTC paths fail visibly. ChannelProfile / ClientRole / AudioProfile constants exposed for type-checked code",missing:"no Agora SDK on web here \u2014 recommended swap: use the Agora Web SDK directly through a host iframe"}]},"expo-maps":{category:"Maps",stubType:"native",versions:[{range:">=0.10.0",coverage:.6,note:"load-safe noop \u2014 AppleMaps / GoogleMaps namespaces with View / Marker / Polyline / Polygon / Circle components rendering null; PROVIDER_GOOGLE / PROVIDER_DEFAULT / MapType enums exposed",missing:"no MKMapView / GoogleMap host views. recommended swap on web: a real react-leaflet or Mapbox GL JS surface in a host iframe"}]},"react-native-ble-manager":{category:"Device & Platform",stubType:"native",versions:[{range:">=11.0.0",coverage:1,note:"load-safe noop \u2014 start/scan accept; connect rejects; getConnectedPeripherals returns []; full BleEventType / BleScanCallbackType / BleScanMode / BleAndroidPhyType / BleState enum surface",missing:"no Web Bluetooth bridging in this stub \u2014 apps that absolutely need BLE should branch on checkState=off"}]},voltra:{category:"Analytics",stubType:"native",versions:[{range:">=0.0.1",coverage:.95,note:"load-safe noop \u2014 initialize accepted; getStatus reports uninitialized",missing:"package surface stubbed loosely; no real analytics delivery"}]},"react-native-enriched":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 EnrichedTextEditor / EnrichedTextInputView / EnrichedTextRenderer pass children through",missing:"no native rich-text editing \u2014 use contenteditable or a lib like @10play/tentap-editor for web"}]},"react-native-enriched-markdown":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 Editor passes children through",missing:"no native markdown editing \u2014 recommended swap: marked/markdown-it + textarea on web"}]},"react-native-emoji-popup":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.6,note:"load-safe noop \u2014 EmojiPopup component passes children through; OS emoji input is the right path on web",missing:"no native emoji picker UI in browser preview"}]},"react-native-audio-api":{category:"Media",stubType:"native",versions:[{range:">=0.5.0",coverage:1,note:"load-safe pass-through \u2014 uses globalThis.AudioContext / OfflineAudioContext when present (Web Audio API). browsers have these natively",missing:"no JSI fast-path; performance differs from native iOS/Android implementation but the API surface matches"}]},"@lodev09/react-native-exify":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:'load-safe error stub \u2014 readAsync / writeAsync reject with clear "not yet bridged" message',missing:"EXIF parsing could be polyfilled with exifr or piexifjs (deferred)"}]},"clevertap-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"load-safe noop \u2014 full singleton + push permission + inbox API accepted; no telemetry delivered",missing:"no real analytics / in-app messaging / push delivery"}]},"@callstack/liquid-glass":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 LiquidGlassView passes children through; sootsim has its own blur primitives",missing:"no native iOS visual effect; consumers can substitute expo-blur which we already polyfill"}]},"react-native-shake":{category:"Device & Platform",stubType:"native",versions:[{range:">=5.0.0",coverage:.6,note:"load-safe noop \u2014 addListener returns a removable subscription that never fires",missing:"browsers have DeviceMotion but require explicit user permission and a different event setup"}]},"react-native-ssl-public-key-pinning":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 initialize=false / isInitialized=false",missing:"browsers cannot intercept TLS; SSL pinning is a native-only concern"}]},"react-native-document-scanner-plugin":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 scanDocument rejects clearly",missing:"no VNDocumentCameraViewController in browser; recommended swap: getUserMedia + opencv.js or document-scanning JS lib"}]},"react-native-system-navigation-bar":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 every set/show/hide method accepted; sootsim Android lane handles its own system bars",missing:"iOS / web have no equivalent system nav bar control"}]},"react-native-volume-manager":{category:"Media",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 getVolume returns 0.5; setVolume / showNativeVolumeUI accepted; isInSilentMode=false; listeners never fire",missing:"browsers cannot modify system volume; only the per-element <audio> volume is mutable from JS"}]},"react-native-navigation":{category:"Navigation",stubType:"native",versions:[{range:">=7.0.0",coverage:.6,note:"load-safe noop \u2014 Navigation singleton with setRoot / push / pop / showModal / dismissModal / events()/registerComponent accepted; nothing renders since this is a native router. recommended swap on web: react-navigation or @one/router which we already polyfill",missing:"no native screen container; subscribers never fire"}]},"@dr.pogodin/react-native-fs":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:'load-safe stub \u2014 DocumentDirectoryPath / CachesDirectoryPath / TemporaryDirectoryPath / ExternalDirectoryPath / LibraryDirectoryPath / PicturesDirectoryPath / DownloadDirectoryPath / MainBundlePath constants exposed; readFile / writeFile / unlink / stat / mkdir / moveFile / copyFile reject with "use react-native-blob-util" suggestion',missing:"no IDB-backed FS in this stub; consumers should migrate to react-native-blob-util which we score at 0.85"}]},"stream-chat-expo":{category:"Notifications",stubType:"native",versions:[{range:">=8.0.0",coverage:.55,note:"load-safe passthrough \u2014 Channel / ChannelList / Chat / MessageList / MessageInput / Thread / OverlayProvider pass children through; useChannelContext / useMessageContext / useChatContext return empty objects so consumers can render their UI without crashing",missing:"no real Stream client wired (depends on heavy native modules: audio, haptics, video). recommended on web: stream-chat-react"}]},"@giphy/react-native-sdk":{category:"UI Components",stubType:"native",versions:[{range:">=4.0.0",coverage:.7,note:"load-safe noop \u2014 GiphySDK.configure noop; GiphyDialog.show/hide accept; GiphyContent.searchQuery / trending construct config objects; full Direction / MediaType / Rating / Theme / ContentType / ImageType enum surface",missing:"no native picker UI; no real GIF delivery. recommended swap: @giphy/js-sdk + custom React UI on web"}]},"react-native-version-number":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.4.0",coverage:1,note:'load-safe defaults \u2014 appVersion="0.0.0", buildVersion="1", bundleIdentifier="sootsim.app". consumers can override via env vars at build time',missing:"no Info.plist / build.gradle reading"}]},"@rudderstack/rudder-sdk-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.95,note:"load-safe noop \u2014 RudderClient with full setup/identify/track/screen/group/alias/reset/flush/optOut accepted",missing:"no real telemetry delivery \u2014 recommended swap: @rudderstack/analytics-js on web"}]},"sp-react-native-in-app-updates":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 checkNeedsUpdate reports shouldUpdate=false; startUpdate/installUpdate accepted; IAUInstallStatus / IAUUpdateKind enums exposed",missing:"no Play / App Store update prompt \u2014 apps gate UI on shouldUpdate=false"}]},"@10play/tentap-editor":{category:"UI Components",stubType:"native",versions:[{range:">=0.7.0",coverage:.55,note:"load-safe passthrough \u2014 RichText / Toolbar pass children through; useEditorBridge returns idle bridge with injectJS / setContent / setSelection / setEditable / getEditorState / getHTML / getJSON / getText accepted; CoreBridge / TenTapStartKit exposed",missing:"no WebView-backed editor \u2014 consumers see editor layout but interactions are inert"}]},"@react-native-firebase/database":{category:"Storage & Data",stubType:"native",versions:[{range:">=21.0.0",coverage:.45,note:"load-safe error stub \u2014 RTDB requires native module. recommended swap: firebase-admin / firebase Web SDK + @firebase/database",missing:"no real-time database \u2014 consumers should use the regular Firebase Web SDK"}]},"@react-native-firebase/in-app-messaging":{category:"Notifications",stubType:"native",versions:[{range:">=21.0.0",coverage:.6,note:"load-safe noop \u2014 isMessagesDisplaySuppressed=false / setMessagesDisplaySuppressed accepted; isAutomaticDataCollectionEnabled=true; triggerEvent accepted but no IAM displayed",missing:"no native IAM UI in browser preview"}]},"@adobe/react-native-aepcore":{category:"Analytics",stubType:"native",versions:[{range:">=8.0.0",coverage:.6,note:"load-safe noop \u2014 MobileCore singleton + Identity / Lifecycle / Signal namespaces accepted; LogLevel / PrivacyStatus enums exposed",missing:"no Adobe Experience Platform delivery in browser preview"}]},"@rnw-community/react-native-payments":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"load-safe pass-through \u2014 forwards to globalThis.PaymentRequest where supported (browsers have W3C Payment Request API natively in some contexts)",missing:"no Apple Pay / Google Pay native fallback \u2014 apps fall back to PaymentRequest if available"}]},"react-native-sensitive-info":{category:"Auth & Payments",stubType:"native",versions:[{range:">=6.0.0",coverage:1,note:"partial \u2014 getItem / setItem / deleteItem / hasItem / getAllItems backed by localStorage with __soot_sensitive_ prefix; biometric helpers (hasEnrolledFingerprints / isSensorAvailable) report false",missing:"no real biometric gating; recommended swap: react-native-keychain (already 0.85 in our registry)"}]},"react-native-turbo-image":{category:"Image",stubType:"native",versions:[{range:">=4.0.0",coverage:.55,note:"load-safe passthrough \u2014 TurboImage pass-through fires onSuccess once via queueMicrotask; prefetch / clearMemoryCache / clearDiskCache accepted",missing:"no Glide / SDWebImage backing \u2014 apps see image layout via underlying fetch / <img>; recommended swap: expo-image (already in our stubs)"}]},"@maplibre/maplibre-react-native":{category:"Maps",stubType:"native",versions:[{range:">=10.0.0",coverage:.55,note:"load-safe passthrough \u2014 MapView / Camera / ShapeSource / FillLayer / LineLayer / SymbolLayer / CircleLayer / RasterSource / RasterLayer pass children through; setAccessToken / setTelemetryEnabled accepted; StyleURL constants exposed",missing:"no maplibre-gl-js host iframe wired \u2014 recommended swap on web: maplibre-gl-js directly"}]},"react-native-avoid-softinput":{category:"Keyboard",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 AvoidSoftInputView pass-through; setEnabled / setShouldMimicIOSBehavior / setAvoidOffset / setEasing / set*Duration / setAdjust* / setDefaultAppSoftInputMode / addListener accepted; sootsim handles keyboard avoidance via its own KeyboardAvoidingView pipeline",missing:"no programmatic keyboard offset \u2014 sootsim KeyboardAvoidingView is the right primary path"}]},"react-native-calendar-events":{category:"Calendar",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 requestPermissions / checkPermissions return denied; findCalendars / fetchAllEvents return []; saveEvent rejects",missing:"no EventKit / CalendarContract in browser preview"}]},"react-native-add-calendar-event":{category:"Calendar",stubType:"native",versions:[{range:">=4.0.0",coverage:.45,note:"load-safe error stub \u2014 present*Dialog rejects",missing:"no system calendar dialog"}]},"@react-native-documents/viewer":{category:"Storage & Data",stubType:"native",versions:[{range:">=10.0.0",coverage:.55,note:"load-safe noop \u2014 DocumentViewerView renders null; isDocumentViewerAvailable=false",missing:"no QLPreviewController / ACTION_VIEW; recommended swap: an iframe with a PDF.js or similar JS viewer"}]},"rn-qr-generator":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 generate / detect reject",missing:"QR encode/decode could be polyfilled with qrcode.js + jsQR (deferred)"}]},"@clerk/expo":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 ClerkProvider pass-through; useUser/useAuth/useSignIn/useSignUp/useClerk/useSession/useSessionList/useOrganization/useOrganizationList/useReverification/useOAuth report unauthenticated state with isLoaded=true so apps gate UI off; SignedIn/SignedOut/Protect/ClerkLoaded/ClerkLoading components also passthrough",missing:"no real Clerk auth \u2014 recommended swap: @clerk/clerk-react on web"}]},"react-native-ui-lib":{category:"UI Components",stubType:"native",versions:[{range:">=7.0.0",coverage:1,note:"load-safe passthrough \u2014 Toast / Picker / Drawer / ActionSheet pass children through; the pure-JS half (Colors / Typography / Spacings tokens) is loaded directly from the consumer's bundle without going through this stub",missing:"native parts of ui-lib (Picker spinner, ActionSheet UI) are not delivered; UI looks plain"}]},"react-native-pdf-renderer":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 PdfRendererView renders null",missing:"no native PDF rendering; recommended swap: PDF.js iframe"}]},"react-native-a11y-order":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.7,note:"upstream react-native-a11y-order JS runs unchanged; native codegen components resolve through sootsim requireNativeComponent/codegenNativeCommands",working:"A11y.Order, A11y.Index, A11y.Group, A11y.Container",missing:"native accessibility traversal order hints; sootsim a11y tree is still engine-derived"}]},"react-native-animateable-text":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no per-character animation surface"}]},"react-native-advanced-input-mask":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe passthrough \u2014 formatMask returns input unchanged",missing:"no input formatting; consumers should use a JS-only library on web"}]},"react-native-otp-verify":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 getOtp resolves empty; getHash resolves a placeholder hash; Android-only SMS Retriever has no browser equivalent",missing:"no SMS Retriever"}]},"@survicate/react-native-survicate":{category:"Analytics",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 full singleton + survey listener accepted",missing:"no real survey delivery"}]},"react-native-navigation-bar-color":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 Android system nav bar color setter accepted",missing:"iOS / web have nothing equivalent"}]},"@react-native-community/image-editor":{category:"Image",stubType:"native",versions:[{range:">=4.0.0",coverage:.92,note:"native-seam: the ImageEditor class + header normalization run from the bundle; the RNCImageEditor TurboModule mirrors upstream's own src/index.web.ts canvas crop (worker-safe OffscreenCanvas) and persists the result into the shared expo-file-system cache VFS so uri/path round-trip \u2014 matching the native 'stored in the Cache Path' contract",working:"cropImage with offset/size source rect, displaySize scaling, format (png/jpeg/webp), quality, includeBase64 (raw base64 without the data: prefix, iOS/Android parity), remote images with custom headers, file:// inputs read from the shared VFS; full CropResult (path/uri/name/width/height/size/type)",missing:"resizeMode is accepted but not honored (upstream src/index.web.ts also ignores it \u2014 drawImage scales to displaySize); same behavior as upstream web"}]},"react-native-localization-settings":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"partial \u2014 getLanguage uses navigator.language; setLanguage / openSystemSettings noop",missing:"cannot set system language from browser"}]},"react-native-mmkv-storage":{category:"Storage & Data",stubType:"native",versions:[{range:">=0.10.0",coverage:.6,note:"alias for react-native-mmkv (which we polyfill at higher coverage)",missing:"sub-API differences \u2014 consumers should migrate to react-native-mmkv"}]},"react-native-restart-newarch":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.5.0",coverage:1,note:"partial \u2014 Restart() calls location.reload() on web",missing:"app-state reset semantics differ from a real RN reload"}]},"react-native-keyboard-manager":{category:"Keyboard",stubType:"native",versions:[{range:">=6.0.0",coverage:.6,note:"load-safe noop \u2014 IQKeyboardManager-style helper. sootsim handles keyboard avoidance via its own pipeline",missing:"iOS-only library; setEnable/setEnableAutoToolbar/etc accepted but inert"}]},"react-native-google-cast":{category:"Media",stubType:"native",versions:[{range:">=4.0.0",coverage:.55,note:"load-safe noop \u2014 getCastState reports NoDevicesAvailable; CastButton renders null; useCastSession=null; useDevices=[]; useCastState=NoDevicesAvailable",missing:"no Chromecast device discovery / cast"}]},"@stream-io/flat-list-mvcp":{category:"UI Components",stubType:"works",versions:[{range:">=0.2.0",coverage:.95,note:'NOT stubbed \u2014 on iOS the package is literally `export default FlatList from "react-native"` (the MvcpScrollViewManager native module is android-only), so it runs from the bundle on sootsim\'s FlatList, which fully supports maintainVisibleContentPosition. drop-in FlatList/ScrollView replacements behave identically to the RN primitives sootsim already implements.',working:"FlatList / ScrollView default + named exports (resolve to sootsim FlatList/ScrollView via the package's iOS variant), maintainVisibleContentPosition prop honored by the engine scroll path, all FlatList/ScrollView props/imperative API (sootsim primitives)",missing:"android-only MvcpScrollViewManager fine-tuning (mvcpTuner) \u2014 not reached on the iOS code path"}]},"stream-chat-react-native":{category:"Notifications",stubType:"native",versions:[{range:">=8.0.0",coverage:.55,note:"identical surface to stream-chat-expo \u2014 passthrough children for Channel/Chat/MessageList components",missing:"same as stream-chat-expo \u2014 recommended swap: stream-chat-react"}]},"react-native-external-keyboard":{category:"Keyboard",stubType:"native",versions:[{range:">=2.0.0",coverage:.7,note:"upstream react-native-external-keyboard JS runs unchanged; native focus host components and commands resolve through sootsim codegen/requireNativeComponent seams",working:"withKeyboardFocus, KeyboardFocusView, BaseKeyboardView, ExternalKeyboardView, Pressable, KeyboardExtendedPressable, KeyboardExtendedInput/TextInput, KeyboardFocusGroup, KeyboardOrderFocusGroup, useIsViewFocused, Keyboard.dismiss",missing:"no hardware-keyboard focus tracking \u2014 sootsim runs on a virtual keyboard"}]},"react-native-wifi-reborn":{category:"Networking",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 loadWifiList=[]; isEnabled=false; connectToProtectedSSID rejects",missing:"browsers cannot enumerate / configure WiFi networks"}]},"react-native-bluetooth-state-manager":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"load-safe noop \u2014 getState reports PoweredOff; full BluetoothState enum exposed",missing:"browsers cannot read Bluetooth adapter state"}]},"react-native-drop-shadow":{category:"UI Components",stubType:"native",versions:[{range:">=0.1.0",coverage:.55,note:"load-safe passthrough",missing:"iOS-specific UIView shadow; CSS box-shadow on web is the right path"}]},"expo-health-connect":{category:"Health",stubType:"native",versions:[{range:">=4.0.0",coverage:.75,note:"alias for react-native-health-connect \u2014 same noop coverage",missing:"no Android Health Connect on iOS / web"}]},"react-native-print":{category:"Storage & Data",stubType:"native",versions:[{range:">=0.10.0",coverage:.6,note:"load-safe noop \u2014 print() accepted",missing:"browsers have window.print() but the API surface differs"}]},"@hot-updater/react-native":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.10.0",coverage:.6,note:"load-safe noop \u2014 runUpdateProcess accepted; useHotUpdater reports idle",missing:"no OTA update mechanism in browser preview"}]},"@pusher/pusher-websocket-react-native":{category:"Networking",stubType:"native",versions:[{range:">=1.2.0",coverage:.45,note:"load-safe noop \u2014 Pusher.getInstance returns a noop client; connect rejects with native bridge unavailable",missing:"recommended swap: @pusher/pusher-js on web"}]},"react-native-voip-push-notification":{category:"Notifications",stubType:"native",versions:[{range:">=10.0.0",coverage:.6,note:'load-safe noop \u2014 addEventListener returns removable subscription; requestPermissions reports denied; getVoipToken=""',missing:"no PushKit / VoIP push channel in browser"}]},"react-native-background-actions":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 start/stop accepted; isRunning=false",missing:"no foreground service / background task"}]},"react-native-screenshot-aware":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.0.1",coverage:.6,note:"load-safe noop \u2014 addListener returns removable subscription that never fires",missing:"browsers cannot detect screenshots"}]},"@iterable/expo-plugin":{category:"Notifications",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"load-safe noop \u2014 expo plugin function returns empty config",missing:"config plugin runs at build time; runtime is the iterable-react-native-sdk path"}]},"react-native-navigation-mode":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 getNavigationMode reports three-button; NavigationMode enum exposed",missing:"no Android system gesture/3-button mode reading on iOS / web"}]},"@okta/okta-react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:'load-safe noop \u2014 createConfig accepted; signIn rejects with "use @okta/okta-auth-js" suggestion; isAuthenticated=false',missing:"no native OIDC flow \u2014 recommended swap: @okta/okta-auth-js"}]},"react-native-snackbar":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.7,note:"load-safe noop \u2014 show/dismiss accepted; LENGTH_LONG/SHORT/INDEFINITE constants exposed",missing:"no Material Snackbar UI on iOS / web; recommended swap: sootsim Toast (already polyfilled)"}]},"react-native-android-widget":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.13.0",coverage:.6,note:"load-safe noop \u2014 requestWidgetUpdate / requestWidgetUpdateById accepted",missing:"iOS / web have no Android home screen widgets"}]},"react-native-system-setting":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.7.0",coverage:.6,note:"load-safe noop \u2014 getVolume=0.5; getBrightness=0.5; isWifiEnabled=false; isLocationEnabled=false; isBluetoothEnabled=false; isAirplaneEnabled=false; all listeners never fire",missing:"browsers cannot read / set system-level settings"}]},"react-native-network-info":{category:"Networking",stubType:"native",versions:[{range:">=5.0.0",coverage:.6,note:"load-safe noop \u2014 getSSID/getBSSID/getBroadcast/getIPAddress all return null",missing:"browsers cannot read Wi-Fi info or LAN IP"}]},"react-native-razorpay":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:'load-safe error stub \u2014 open() rejects with "use razorpay web checkout"',missing:"no native checkout sheet; recommended swap: Razorpay Web Checkout"}]},"react-native-play-age-range-declaration":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 getCurrentAgeRange=0 (unspecified)",missing:"no Google Play age range API on iOS / web"}]},"react-native-spinkit":{category:"UI Components",stubType:"native",versions:[{range:">=1.5.0",coverage:1,note:"load-safe passthrough \u2014 Spinner renders children; full Type enum exposed",missing:"no animation; recommended swap: pure-JS spinner like react-spinners"}]},"react-native-version-info":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:'load-safe defaults \u2014 appVersion="0.0.0", buildVersion="1", bundleIdentifier="sootsim.app"',missing:"consumers should override via env vars at build time"}]},"react-native-moengage":{category:"Analytics",stubType:"native",versions:[{range:">=10.0.0",coverage:.95,note:"load-safe noop \u2014 full singleton accepted; no telemetry / nudge UI delivered",missing:"no real MoEngage SDK; recommended swap: @moengage/web-sdk on web"}]},"react-native-nitro-sound":{category:"Media",stubType:"native",versions:[{range:">=0.5.0",coverage:.6,note:"load-safe noop \u2014 Nitro.startRecorder/startPlayer accepted; addRecordBack/PlayBackListener return removable subscriptions",missing:"no native record/play audio engine; consumers can use Web Audio + getUserMedia directly"}]},"react-native-touch-id":{category:"Auth & Payments",stubType:"native",versions:[{range:">=4.0.0",coverage:.85,note:"native-seam: the pure-JS TouchID wrapper + errors.js + data/errors.js (TouchIDError classes + iOSErrors map) run from the real bundle; only NativeModules.TouchID is ours, mirroring TouchID.m on the reference iOS Simulator (Face ID device, no biometrics enrolled, no passcode): canEvaluatePolicy fails with LAErrorTouchIDNotEnrolled and passcodeFallback defaults false, so isSupported/authenticate call back with that error reason and the real wrapper rejects with the faithful NOT_ENROLLED TouchIDError \u2014 the exact value a guest gets on the reference device. same faithful tier as expo-local-authentication.",working:"isSupported(config) and authenticate(reason, config) \u2014 real upstream wrapper + TouchIDError/TouchIDUnifiedError + iOSErrors mapping run from the bundle off a faithful native callback; reference-simulator parity (rejects with LAErrorTouchIDNotEnrolled \u2192 NOT_ENROLLED)",missing:"no real biometric prompt can succeed \u2014 but neither can the reference iOS Simulator (no enrolled biometrics); package is deprecated upstream (expo-local-authentication is the maintained successor, also a faithful native-seam here)"}]},"react-native-app-clip":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.9.0",coverage:.6,note:"load-safe noop \u2014 isAppClip=false; getUserActivity=null",missing:"no Apple App Clip surface in browser"}]},"react-native-localization":{category:"Internationalization",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"load-safe class \u2014 setLanguage / getLanguage / getInterfaceLanguage / getAvailableLanguages backed by navigator.language",missing:"no Localizable.strings reading; consumers should use upstream Localizable strings via JSON imports"}]},"@react-native-firebase/app-distribution":{category:"Device & Platform",stubType:"native",versions:[{range:">=21.0.0",coverage:.6,note:"load-safe noop \u2014 isTesterSignedIn=false; signInTester rejects; checkForUpdate=null",missing:"no Firebase App Distribution in browser"}]},"react-native-wallet-manager":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 canAddPasses=false; addPass / addPassFromUrl reject",missing:"no native PassKit / Google Pay Wallet on web"}]},"react-native-blurhash":{category:"Image",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 Blurhash component renders null",missing:"no blurhash decoding; recommended swap: a JS implementation like blurhash npm package"}]},"expo-alternate-app-icons":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 setAlternateAppIcon accepted; getAlternateAppIcon=null; isAlternateAppIconSupported=false",missing:"no UIApplication.setAlternateIconName equivalent in browser"}]},"react-native-send-intent":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 Android-only ACTION_* helpers reject; isAppInstalled=false; openApp=false",missing:"iOS / web have no ACTION_SEND equivalent"}]},"react-native-select-contact":{category:"Calendar",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 selectContact / selectContactPhone / openContact resolve null",missing:"no system contact picker on web"}]},"react-native-watch-connectivity":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.1.0",coverage:.6,note:"load-safe noop \u2014 getReachability/getInstalled/getIsPaired all false; sendMessage resolves empty; useReachability/useInstalled/usePaired hooks return false",missing:"browsers cannot pair with watchOS / Wear OS hardware"}]},"react-native-shared-group-preferences":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 setItem accepted; getItem=null; isAppGroupShared=false",missing:"no App Group container outside of iOS"}]},"react-native-mail":{category:"Storage & Data",stubType:"native",versions:[{range:">=6.0.0",coverage:.85,note:"native-seam: real one-line package (export default NativeModules.RNMail) runs from the bundle; the RNMail native module faithfully mirrors the iOS-simulator contract \u2014 upstream ios/RNMail.m guards mail() with [MFMailComposeViewController canSendMail], which is false on a sim with no Mail account, so it calls back 'not_available'. same faithful-unavailable stance and tier as the expo-mail-composer native seam.",working:"mail(options, callback) \u2192 callback('not_available') exactly as upstream RNMail.m does when canSendMail is false; apps that handle the documented error callback take the correct branch",missing:"no real mail composer UI (the iOS simulator has none either \u2014 this is faithful iOS-sim behavior, not a sootsim-specific gap)"}]},"expo-superwall":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 Superwall.configure/identify/registerEvent/registerPlacement/preloadAllPaywalls accepted; getPresentationResult=paywallNotPresented; presentPaywallForEvent=noPaywallToPresent",missing:"no real Superwall paywall delivery \u2014 Superwall has a Web SDK that consumers should use directly on web"}]},"@preeternal/react-native-cookie-manager":{category:"Networking",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 set/setFromResponse accepted; get/getFromResponse return empty; clearAll/clearByName/flush accepted",missing:"no native cookie store; on web document.cookie is the right API but cross-origin reads are blocked"}]},"@stream-io/video-react-native-sdk":{category:"Networking",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough \u2014 StreamVideo / StreamCall / CallContent / RingingCallContent / IncomingCall / OutgoingCall pass children through; useCalls=[]; useStreamVideoClient=null",missing:"no real Stream Video client \u2014 recommended swap: @stream-io/video-react-sdk on web"}]},"react-native-shared-element":{category:"Animation",stubType:"native",versions:[{range:">=0.8.0",coverage:.55,note:"load-safe passthrough \u2014 SharedElement / SharedElementTransition pass children through; nodeFromRef=null",missing:"no native shared-element transitions; Framer Motion or react-native-reanimated layout is the right web/RN path"}]},"@react-native-ml-kit/text-recognition":{category:"ML",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe error stub \u2014 recognize rejects; TextRecognitionScript constants exposed",missing:"no ML Kit on web; recommended swap: tesseract.js or vision API endpoint"}]},"react-native-star-io10":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe stub \u2014 InterfaceType / StarConnectionSettings exposed; StarPrinter throws on construction",missing:"no Star receipt printer hardware in browser"}]},"llama.rn":{category:"ML",stubType:"native",versions:[{range:">=0.5.0",coverage:.45,note:"load-safe error stub \u2014 initLlama rejects; convertJsonSchemaToGrammar returns empty",missing:"no llama.cpp runtime in browser; recommended swap: web-llm or remote inference endpoint"}]},"@react-native-community/progress-bar-android":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 ProgressBarAndroid renders null",missing:"Android-only; iOS / web have ActivityIndicator equivalents"}]},"react-native-file-logger":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.7,note:"load-safe noop \u2014 debug/info/warn/error accepted; getLogFilePaths=[]; full LogLevel enum exposed",missing:"no file system writes \u2014 browsers route logs to console.* instead"}]},"@renegades/react-native-tickle":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.0.1",coverage:.6,note:"load-safe noop \u2014 tickle accepted",missing:"no haptic API exposed by this stub; consumers should use expo-haptics"}]},"expo-in-app-updates":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 checkForUpdate=false; startUpdate accepted; addUpdateListener returns removable subscription",missing:"no Play / App Store update prompts in browser"}]},"react-native-pkce-challenge":{category:"Auth & Payments",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 returns empty codeVerifier/codeChallenge",missing:"consumers should use a proper PKCE library like @noble/hashes on web"}]},"react-native-ux-cam":{category:"Analytics",stubType:"native",versions:[{range:">=5.0.0",coverage:.6,note:"load-safe noop \u2014 full singleton accepted; no session recording / heatmap delivery",missing:"no real UXCam recording"}]},"react-native-barcode-creator":{category:"Media",stubType:"native",versions:[{range:">=2.0.0",coverage:.65,note:"load-safe noop \u2014 BarcodeCreatorView renders null; full Type enum exposed",missing:"no native barcode generation; recommended swap: bwip-js"}]},"react-native-widgetkit":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 getCurrentConfigurations={}; reload* accepted",missing:"no WidgetKit on iOS / web"}]},"react-native-theoplayer":{category:"Media",stubType:"native",versions:[{range:">=8.0.0",coverage:.55,note:"load-safe noop \u2014 THEOplayerView renders null; PlayerEventType enum exposed",missing:"no THEOplayer player on web \u2014 consumers should use theoplayer Web SDK"}]},"@google/react-native-make-payment":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 isReadyToPay=false; requestPayment rejects",missing:"recommended swap: Google Pay JS API on web"}]},"react-native-change-icon":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:'load-safe noop \u2014 changeIcon rejects; getIcon="default"; resetIcon noop',missing:"duplicate of expo-alternate-app-icons capability"}]},"@react-native-community/progress-view":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 ProgressView renders null",missing:"iOS UIProgressView; consumers can render their own bar in web"}]},"react-native-prompt-android":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"partial \u2014 uses window.prompt() when available so callbacks fire with the entered value",missing:"no Material AlertDialog on iOS; window.prompt is the closest browser equivalent"}]},"react-native-text-size":{category:"UI Components",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:'load-safe noop \u2014 measure/flatHeights resolve zero-sized; fontFamilyNames=["system"]',missing:"no native text measurement; consumers should use canvas measureText on web"}]},"react-native-adapty":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 adapty.activate/identify/logout/getProfile accepted; getPaywall/makePurchase reject; restorePurchases resolves empty access levels",missing:"recommended swap: @adapty/web-sdk on web"}]},"@twilio/voice-react-native-sdk":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 Voice.register / connect reject",missing:"recommended swap: @twilio/voice-sdk on web"}]},"react-native-fast-tflite":{category:"ML",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 loadTensorflowModel rejects; useTensorflowModel reports error state",missing:"no tflite runtime; recommended swap: tensorflow.js"}]},"react-native-screenguard":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 register/registerWith*/unregister accepted; screenshot/recording listeners never fire",missing:"browsers cannot detect / prevent screenshots"}]},"react-native-signature-capture":{category:"UI Components",stubType:"native",versions:[{range:">=0.4.0",coverage:.55,note:"load-safe noop \u2014 SignatureCapture renders null",missing:"recommended swap: react-signature-canvas on web"}]},"react-native-month-year-picker":{category:"UI Components",stubType:"native",versions:[{range:">=1.9.0",coverage:.55,note:"load-safe noop \u2014 picker renders null; ACTION_DATE_SET / ACTION_DISMISSED / ACTION_NEUTRAL constants exposed",missing:"recommended swap: a JS-only date picker on web"}]},"react-native-nitro-image":{category:"Image",stubType:"native",versions:[{range:">=0.10.0",coverage:.55,note:"load-safe noop \u2014 NitroImage renders null; loadImageFromUrl rejects",missing:"use expo-image (already polyfilled) for browser-fast Image"}]},"react-native-wheel-picker-android":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 WheelPicker renders null",missing:"Android-only; iOS / web should use sootsim Picker"}]},"scandit-react-native-datacapture-core":{category:"Media",stubType:"native",versions:[{range:">=6.0.0",coverage:.45,note:"load-safe error stub \u2014 DataCaptureContext.forLicenseKey rejects; DataCaptureView renders null",missing:"no Scandit native runtime; recommended swap: scandit-web-datacapture-core"}]},"@sbaiahmed1/react-native-biometrics":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 isSensorAvailable reports unavailable; simplePrompt resolves success=false; createKeys/createSignature resolve empty",missing:"recommended swap: WebAuthn (browser) for biometric flows"}]},"react-native-splash-view":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 show/hide accepted",missing:"sootsim handles splash via expo-splash-screen (already polyfilled)"}]},"react-native-legal":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 launchLicenseList accepted; addLicense / setLibraryName accepted",missing:"no native UI; consumers should render licenses themselves on web"}]},"react-native-fast-shadow":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no native shadow blur; CSS box-shadow on web is the right path"}]},"@react-native-community/toolbar-android":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"Android-only; iOS / web have nothing equivalent \u2014 header is the typical replacement"}]},"react-native-nitro-web-image":{category:"Image",stubType:"native",versions:[{range:">=0.5.0",coverage:.55,note:"load-safe noop \u2014 NitroWebImage renders null",missing:"use expo-image (already polyfilled)"}]},"react-native-bluetooth-classic":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.75,note:"load-safe noop \u2014 isBluetoothAvailable=false; getBondedDevices=[]; pairDevice/connectToDevice/accept reject; startDiscovery=[]",missing:"browsers have Web Bluetooth (BLE only); Bluetooth Classic / SPP unsupported"}]},"@logicwind/react-native-exit-app":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.1.0",coverage:.85,note:"native-seam: a maintained fork of react-native-exit-app with the identical single-method contract \u2014 the exitApp() wrapper runs from the bundle; the only native part is the `ExitApp` NativeModule (vs RNExitApp upstream), a faithful no-op. this IS the complete correct contract, not a gap: Apple\u2019s HIG forbids App Store apps from self-terminating and a browser cannot close its tab, so an app calling exitApp() on real iOS already gets nothing user-visible. same faithful tier as react-native-exit-app / react-native-orientation-locker.",working:"exitApp() \u2014 matches upstream\u2019s exact single-method surface; faithful complete behavior (no-op, as on real iOS App Store apps)",missing:"none functionally \u2014 the package\u2019s sole purpose (terminate the app) is intentionally unavailable on both iOS App Store apps and browsers; the no-op is the faithful contract, not an unimplemented feature"}]},"@xmartlabs/react-native-line":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 LineLogin.login rejects; setup / logout / getCurrentAccessToken accepted",missing:"recommended swap: @line/liff on web"}]},"react-native-get-location":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.92,note:"native-seam: package JS (LocationError, isLocationError, android permission, openSettings via Linking) runs from the bundle; the RNGetLocation TurboModule is backed by navigator.geolocation (the documented web equivalent), with the rejection shape upstream isLocationError() expects",working:"getCurrentPosition (enableHighAccuracy + timeout honored; full Location mapping incl. altitude/accuracy/speed/time and iOS verticalAccuracy/course from altitudeAccuracy/heading), error codes mapped to UNAUTHORIZED/TIMEOUT/UNAVAILABLE, openSettings via RN Linking, LocationError class + isLocationError guard",missing:"browser geolocation requires a user permission grant (denied \u2192 UNAUTHORIZED, same as a denied native prompt); altitude/speed are 0 and verticalAccuracy/course are -1 when the browser does not supply them"}]},"react-native-screenshot-prevent":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 enabled() accepted; iosProtectFromScreenRecording / iosProtectFromScreenshot accepted",missing:"browsers cannot prevent screenshots"}]},"react-native-file-viewer-turbo":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 open() rejects",missing:"no native QLPreviewController; recommended swap: PDF.js iframe"}]},"react-native-secure-key-store":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"partial \u2014 set/get/remove backed by localStorage with __soot_secure_ prefix; ACCESSIBLE constants exposed",missing:"no real keychain encryption; recommended swap: react-native-keychain (already polyfilled)"}]},"react-native-radial-gradient":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no native radial gradient; CSS radial-gradient on web is the right path"}]},"react-native-cloud-store":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 isICloudAvailable=false; documentsDirectory empty; upload/download reject; listSync=[]",missing:"no iCloud Drive integration in browser"}]},"react-native-screen-corner-radius":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"native-seam: the two pure-JS constants (ScreenCornerRadius, IsScreenRounded) run from the real bundle; only the ScreenCornerRadius NativeModule is ours, and its `cornerRadius` constant returns the live simulated device's display corner radius from the same surface-metrics snapshot the engine renders the device chrome from (iPhone 16 = 55, iPhone 17 Pro = 62, SE = 0, \u2026). this is the package's entire purpose and SootSim answers it precisely \u2014 the same value real iOS reports for that hardware. faithful complete contract, not a no-op.",working:"NativeModules.ScreenCornerRadius.cornerRadius (real per-device radius, synchronous constant read at import like upstream); ScreenCornerRadius + IsScreenRounded constants computed by the real package JS off that value, so IsScreenRounded is correct per device",missing:'none functionally \u2014 returns the exact display corner radius of the simulated device; 0 only in the pre-boot window before the first device spec publishes, which the upstream `?? 0` already treats as "couldn\'t be detected"'}]},"freerasp-react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 startFreeRasp accepted; isAppInDebug/isAppTampered=false",missing:"no RASP (runtime application self-protection) in browser"}]},"react-native-orientation-director":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.7,note:"load-safe noop \u2014 getInitialOrientation/getDeviceOrientation/getInterfaceOrientation report Portrait; lockTo/unlock accepted; full Orientation enum exposed",missing:"sootsim canvas is portrait-only; this matches"}]},"expo-squircle-view":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no native squircle clip-path; CSS clip-path on web is the right path"}]},"scandit-react-native-datacapture-barcode":{category:"Media",stubType:"native",versions:[{range:">=6.0.0",coverage:.55,note:"load-safe error stub \u2014 BarcodeCapture.forContext rejects; Symbology constants exposed",missing:"recommended swap: scandit-web-datacapture-barcode"}]},"react-native-a11y":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe passthrough",missing:"sootsim a11y tree is the right native path"}]},"expo-live-activity":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 startActivity rejects; updateActivity/endActivity accepted; listActivities=[]; requestPermissions=denied; isActivityEnabled=false",missing:"no Dynamic Island / Live Activities outside iOS"}]},"@luciq/react-native":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 full singleton accepted (formerly Shake/Instabug-style)",missing:"no real bug-report SDK delivery"}]},"react-native-safari-view":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 isAvailable=false; show rejects",missing:"no SFSafariViewController in browser; consumers should use sootsim Browser or window.open"}]},"@zoontek/react-native-navigation-bar":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 setStyle/setVisible/setBehavior accepted",missing:"iOS / web have no equivalent"}]},"react-native-webp-format":{category:"Image",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"load-safe partial \u2014 isWebPSupported=true (browsers support WebP); encodeWebP/decodeWebP reject",missing:"WebP reading is via <img>/<canvas>; encoding via Canvas.toBlob"}]},"react-native-photo-manipulator":{category:"Image",stubType:"native",versions:[{range:">=1.0.0",coverage:.92,note:"native-seam: PhotoManipulator + ParamUtils (color/asset normalization, enums) run from the bundle; the RNPhotoManipulator module does the CoreGraphics/Bitmap work in worker-safe 2D canvas and persists the result into the shared expo-file-system cache VFS so the returned uri round-trips (native parity)",working:"crop (+ targetSize resize), flipImage (Horizontal/Vertical/Both), rotateImage (R90/R180/R270), overlayImage, printText (position/size/font/color/rotation/align/direction/shadow), optimize (jpeg quality), batch (crop+resize then chained flip/rotate/overlay/text), file:// inputs from the shared VFS, image/jpeg + image/png output",missing:"printText uses browser font metrics (sans-serif fallback when a native fontName is unavailable) so glyph positioning may differ by sub-pixel amounts from native CoreText/android Paint"}]},"@eabdullazyanov/react-native-sms-user-consent":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 startSmsHandling accepted; listeners never fire",missing:"Android-only SMS Retriever; iOS / web have nothing equivalent"}]},"react-native-keyevent":{category:"Keyboard",stubType:"native",versions:[{range:">=0.3.0",coverage:.6,note:"load-safe noop \u2014 onKeyDown/UpListener register but never fire",missing:"sootsim handles its own keyboard events; consumers can use window keydown/keyup directly"}]},"@callstack/react-native-brownfield":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:1,note:"load-safe passthrough \u2014 children pass through (brownfield-mount of RN inside native host has no browser equivalent)",missing:"sootsim is already a pure-JS host"}]},"react-native-hole-view":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe passthrough \u2014 ECurve constants exposed",missing:"no native cutout; CSS clip-path on web is the right path"}]},"react-native-filament":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 FilamentView/Camera/Light/Model render null; useModel/useEngine/useCamera return null; loadAsset rejects",missing:"no native Filament 3D renderer; recommended swap: three.js / WebGPU on web"}]},"react-native-executorch":{category:"ML",stubType:"native",versions:[{range:">=0.3.0",coverage:.6,note:"load-safe noop \u2014 useLLM reports {generate: rejects, isReady: false}; useImageEmbeddings rejects",missing:"no ExecuTorch runtime; recommended swap: web-llm or remote inference"}]},"react-native-image-marker":{category:"Image",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 markText/markImage reject",missing:"recommended swap: canvas + fillText on web"}]},"@callstack/react-native-visionos":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough \u2014 VolumeView / ImmersiveSpace pass children",missing:"no visionOS host; iOS / web have nothing equivalent"}]},"@didomi/react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 initialize/setUserAgreeToAll/setUserDisagreeToAll/showNotice/showPreferences/reset accepted; isReady=true; EventType enum exposed",missing:"no real Didomi consent collection"}]},"react-native-youtube":{category:"Media",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 YouTube renders null",missing:"no embedded YouTube player; consumers can use the iframe player API directly"}]},"react-native-fast-squircle":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"alias for expo-squircle-view",missing:"CSS clip-path is the web equivalent"}]},"@simform_solutions/react-native-audio-waveform":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 Waveform renders null; PermissionStatus enum exposed",missing:"no native waveform rendering; recommended swap: WaveSurfer.js"}]},"rollbar-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 Client class with init/log/debug/info/warning/error/critical/configure",missing:"no real Rollbar delivery; recommended swap: rollbar.js on web"}]},"@shopify/checkout-sheet-kit":{category:"Auth & Payments",stubType:"native",versions:[{range:">=3.0.0",coverage:.7,note:"load-safe noop \u2014 present rejects; preload/invalidate/configure accepted; ColorScheme constants exposed",missing:"no Shopify checkout sheet; recommended swap: shopify-checkout JS embed"}]},"expo-share-extension":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no iOS share extension target; sootsim cannot run as a system share target"}]},"react-native-video-trim":{category:"Storage & Data",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 showEditor rejects; cleanFiles/closeEditor accepted",missing:"recommended swap: ffmpeg.wasm + video element"}]},"react-native-dialogs":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 showPicker/alert reject",missing:"sootsim Alert / ActionSheet are the right primitives"}]},"@kesha-antonov/react-native-background-downloader":{category:"Networking",stubType:"native",versions:[{range:">=3.0.0",coverage:.6,note:"load-safe noop \u2014 download returns task object with pause/resume/cancel/done/error/begin/progress chains; checkForExistingDownloads=[]",missing:"no background download \u2014 browsers have ServiceWorker fetch but the API differs"}]},"@clerk/expo-passkeys":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no WebAuthn in tenant worker \u2014 needs DOM bridge"}]},"react-native-charts-wrapper":{category:"UI Components",stubType:"native",versions:[{range:">=0.6.0",coverage:.55,note:"load-safe noop \u2014 LineChart/BarChart/PieChart/CandleStickChart/RadarChart/BubbleChart/HorizontalBarChart/ScatterChart/CombinedChart all render null",missing:"no MPAndroidChart/Charts native; recommended swap: victory-native or recharts on web"}]},"react-native-video-cache":{category:"Media",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"load-safe partial \u2014 getCacheUri returns input url; cleanCache/cleanByUrl accepted; getCacheSize=0",missing:"no video proxy/cache; browsers cache via standard HTTP cache"}]},"react-native-tiktok-business-sdk":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 initialize/identify/logout/trackEvent/trackContentEvent accepted",missing:"no real TikTok analytics"}]},"react-native-idle-timer":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.85,note:"native-seam: the 3-line wrapper runs from the bundle; the IdleTimerManager native module backs setIdleTimerDisabled with the real Screen Wake Lock API (navigator.wakeLock) \u2014 the documented web equivalent of UIApplication.isIdleTimerDisabled \u2014 best-effort acquiring/releasing a real screen lock per active tag, with state tracking so multi-tag refcounting stays correct even where Wake Lock is unavailable (insecure origin / hidden tab degrade silently, as an app expects when the OS declines)",working:"setIdleTimerDisabled(disabled, tag) \u2014 acquires a real screen wake lock while any tag is disabled, releases when all are cleared; correct tag refcounting; matches upstream\u2019s exact single-method void surface",missing:"a hidden/background tab cannot hold a Wake Lock (browser releases it on visibilitychange \u2014 same effective behavior as iOS releasing the idle-timer override when the app backgrounds)"}]},"react-native-rate-app":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"native-seam: upstream JS (RateAppError, openStoreForReview via real RN Linking, getAndroidMarketUrl, market-URL constants, AndroidMarket enum) runs from the bundle; the RateApp TurboModule faithfully mirrors the iOS-simulator SKStoreReviewController contract \u2014 requestReview resolves without throwing and the system prompt is a silent no-op (exactly as on a real sim; even on-device the prompt is OS-controlled and rate-limited). same faithful-unavailable tier as react-native-mail / expo-mail-composer.",working:"requestReview / requestReviewGalaxyStore / requestReviewAppGallery (resolve true \u2014 request issued, OS-suppressed display, no throw), openStoreForReview (real Linking.openURL to itms-apps/market URLs), getAndroidMarketUrl, RateAppError, AndroidMarket enum",missing:"no visible in-app rating prompt (the iOS simulator shows none either \u2014 faithful iOS-sim behavior, not a sootsim-specific gap)"}]},"react-native-compass-heading":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"native-seam: the start/stop NativeEventEmitter wrappers run from the bundle; the CompassHeading module backs them with the real DeviceOrientationEvent (webkitCompassHeading on iOS Safari, else the alpha angle converted to a clockwise compass heading \u2014 the same source expo-location.getHeadingAsync uses, kept consistent), emitting the HeadingUpdated { heading, accuracy } events upstream subscribes to, throttled by the caller\u2019s update_rate degree threshold",working:"start(update_rate) (acquires DeviceOrientation permission on iOS Safari, subscribes deviceorientation, emits HeadingUpdated with degree-threshold throttling, returns false when DeviceOrientationEvent is unavailable), stop() (removes the listener), NativeEventEmitter(CompassHeading) HeadingUpdated subscription",missing:"compass accuracy is -1 unless the browser exposes webkitCompassAccuracy (DeviceOrientationEvent.alpha carries no accuracy \u2014 coarser than CLLocationManager, same caveat as expo-location heading)"}]},"@cometchat/chat-uikit-react-native":{category:"Notifications",stubType:"native",versions:[{range:">=4.0.0",coverage:.55,note:"load-safe passthrough \u2014 Conversations/UI/MessageList/MessageComposer/IncomingCall/OutgoingCall/Theme/Localize all pass children",missing:"no real CometChat client; recommended swap: @cometchat/chat-uikit-react"}]},"react-native-tcp":{category:"Networking",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"alias for react-native-tcp-socket",missing:"same as react-native-tcp-socket"}]},"react-native-sfsymbols":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 SFSymbol/SymbolView render null",missing:"use expo-symbols (already polyfilled, blends with proof to higher score)"}]},"@googlemaps/react-native-navigation-sdk":{category:"Maps",stubType:"native",versions:[{range:">=0.6.0",coverage:.55,note:"load-safe passthrough \u2014 NavigationView/NavigationProvider pass children; useNavigation=null",missing:"no Google Maps Navigation SDK on web"}]},"@dr.pogodin/react-native-static-server":{category:"Networking",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:"load-safe error stub \u2014 StaticServer.start rejects; addStateListener returns no-op unsubscribe",missing:"browsers cannot run a server"}]},"react-native-extra-dimensions-android":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 all dimension getters resolve 0",missing:"iOS / web have nothing equivalent"}]},"@rudderstack/rudder-integration-firebase-react-native":{category:"Analytics",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop integration",missing:"no real Firebase integration"}]},"@bravemobile/react-native-code-push":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough \u2014 sync rejects; notifyAppReady accepted; allowRestart/disallowRestart/restartApp accepted",missing:"no OTA hot-update mechanism in browser preview"}]},"@batch.com/react-native-plugin":{category:"Notifications",stubType:"native",versions:[{range:">=8.0.0",coverage:.6,note:"load-safe noop \u2014 Batch singleton + Push/User/Inbox/Profile/Messaging namespaces accepted",missing:"no real Batch.com push delivery"}]},"react-native-background-upload":{category:"Networking",stubType:"native",versions:[{range:">=6.0.0",coverage:.88,note:"native-seam: upstream src/index.js (getFileInfo wrapper, cancelUpload validation, DeviceEventEmitter listeners, default export) runs from the bundle; the VydiaRNFileUploader/RNFileUploader native module does a real XMLHttpRequest upload (the only browser API exposing upload progress), reading the source from the shared expo-file-system VFS and emitting the RNFileUploader-progress/completed/error/cancelled lifecycle on DeviceEventEmitter",working:"startUpload (raw + multipart with field/parameters/headers, PUT/POST), real upload progress events (0-100), completed (responseCode/responseBody), error, cancelUpload \u2192 cancelled event, getFileInfo (exists/size/name/extension/mimeType from the VFS, never rejects)",missing:"no true *background* continuation while the tab is closed (browsers have no equivalent \u2014 the upload runs foreground; same limitation as react-native-fs uploadFiles); tray notification options are accepted but inert (no OS notification surface)"}]},"@shakebugs/react-native-shake":{category:"Analytics",stubType:"native",versions:[{range:">=15.0.0",coverage:.6,note:"load-safe noop \u2014 Shake singleton accepted",missing:"no shake-to-report bug-tool delivery"}]},"expo-dynamic-app-icon":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:'load-safe noop \u2014 setAppIcon/getAppIcon resolve "default"; isSupported=false',missing:"no UIApplication.setAlternateIconName equivalent"}]},"expo-paste-input":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"no native paste handler; sootsim TextInput supports paste natively"}]},"react-native-view-pdf":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 PDFView renders null",missing:"recommended swap: PDF.js iframe"}]},"react-native-nitro-haptics":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.5.0",coverage:.6,note:"load-safe noop \u2014 impact/notification/selection accepted",missing:"sootsim has expo-haptics; consumers should use that"}]},"react-native-google-places-sdk":{category:"Maps",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 initialize accepted; fetchPredictions=[]; fetchPlaceByID rejects",missing:"recommended swap: Google Places API on web directly"}]},"react-native-dynamic-app-icon":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"alias for expo-dynamic-app-icon",missing:"iOS / web have nothing equivalent"}]},"react-native-device-country":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"native-seam: TYPE constants + getCountryCode wrappers run from the bundle; the NativeDeviceCountry TurboModule returns the real device region derived from the runtime locale (Intl.Locale(navigator.language).region, the documented web equivalent of iOS Locale.current.regionCode) instead of a hardcoded value, preserving upstream\u2019s exact { code, type } ResolveType shape",working:"getCountryCode (real ISO region from the runtime locale), getCountryCodeIOS / getCountryCodeAndroid / Platform branch (run from bundle JS), TYPE_ANY / TYPE_TELEPHONY / TYPE_CONFIGURATION constants",missing:"no SIM/telephony MCC lookup (browsers expose only the OS/locale region, not a carrier country \u2014 TYPE_TELEPHONY resolves the same locale region as TYPE_CONFIGURATION)"}]},"react-native-fingerprint-scanner":{category:"Auth & Payments",stubType:"native",versions:[{range:">=6.0.0",coverage:.85,note:'native-seam: the pure-JS src/* wrappers + createError + ERRORS map run from the real bundle (release.ios is pure JS and never touches native); only NativeModules.ReactNativeFingerprintScanner is ours, mirroring ReactNativeFingerprintScanner.m on the reference iOS Simulator (Face ID device, no biometrics enrolled): canEvaluatePolicy(biometrics) fails first in both isSensorAvailable and authenticate with LAErrorBiometryNotEnrolled, which the native maps to the code FingerprintScannerNotEnrolled and returns via RCTJSErrorFromCodeMessageAndNSError, so the real wrapper rejects with the faithful "no enrolled fingers" FingerprintScannerError \u2014 the exact value a guest gets on the reference device. same faithful tier as expo-local-authentication / react-native-touch-id.',working:"isSensorAvailable() and authenticate({ description, fallbackEnabled }) \u2014 real upstream wrappers + FingerprintScannerError + ERRORS mapping run from the bundle off a faithful native callback; release() is upstream pure JS; reference-simulator parity (rejects FingerprintScannerNotEnrolled)",missing:"no real biometric prompt can succeed \u2014 but neither can the reference iOS Simulator (no enrolled biometrics); expo-local-authentication is the maintained alternative, also a faithful native-seam here"}]},"expo-pip":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 startPictureInPicture/stopPictureInPicture accepted; isPipSupported=false",missing:"browsers expose Document.exitPictureInPicture / requestPictureInPicture; sootsim does not bridge yet"}]},"react-native-detector":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 isAvailable=false; detect rejects",missing:"package surface stubbed loosely"}]},"react-native-orientation-turbo":{category:"Device & Platform",stubType:"native",versions:[{range:">=2.0.0",coverage:.85,note:'native-seam: the Orientation/Landscape/Portrait enums + thin wrappers run from the bundle; the OrientationTurbo TurboModule mirrors SootSim\u2019s fixed portrait frame \u2014 lock intent is tracked truthfully (isLocked stays correct), getCurrentOrientation reports the device\u2019s real PORTRAIT orientation, getDeviceAutoRotateStatus returns null exactly as upstream does on iOS, and the change subscriptions are real removable handles whose callbacks never fire (the device never rotates). same faithful "orientation cannot be forced in a browser" stance/tier as react-native-orientation-locker.',working:"startOrientationTracking/stopOrientationTracking, lockToPortrait/lockToLandscape/unlockAllOrientations (intent tracked \u2192 isLocked correct), getCurrentOrientation (PORTRAIT \u2014 real), isLocked, getDeviceAutoRotateStatus (null, faithful iOS), onOrientationChange/onLockOrientationChange (removable subscriptions), all enums",missing:"a browser cannot force device rotation, so lock* does not visually rotate and orientation-change callbacks never fire (faithful iOS-sim/browser limitation, identical to react-native-orientation-locker \u2014 not a sootsim-specific gap)"}]},"@journeyapps/react-native-quick-sqlite":{category:"Storage & Data",stubType:"native",versions:[{range:">=8.0.0",coverage:.85,note:"native-seam: the pure-JS concurrent-lock layer (setup-open.js, type-orm.js, DBListenerManager, lock-hooks, types) runs unchanged from the bundle; only the QuickSQLite NativeModule is ours \u2014 its synchronous install() populates global.__QuickSQLiteProxy with a real bedrock-sqlite-backed proxy sharing the same WASM engine as expo-sqlite/op-sqlite/nitro-sqlite/react-native-sqlite-storage, so persistence lands in the tenant-scoped memfs IDB and survives reload. faithfully implements the PowerSync concurrent-lock model: requestLock/onLockContextIsAvailable/executeInContext/releaseLock serialized per-db over the single-threaded WASM handle (read+write contexts one-at-a-time, FIFO \u2014 exactly how one SQLite connection behaves; the native lib\u2019s extra read connections are a throughput optimization, not an observable semantic). verified end-to-end against the on-disk bedrock build: CRUD, BEGIN/COMMIT, ROLLBACK, executeBatch, lock-context serialization ordering, and close/reopen persistence.",working:"install()/__QuickSQLiteProxy, open/close/delete, requestLock/releaseLock + onLockContextIsAvailable dispatch, executeInContext (real bedrock SQL incl. joins/params/RETURNING), executeBatch, refreshSchema, the upstream setup-open concurrent-connection object (execute, readLock/writeLock, readTransaction/writeTransaction, listener manager) running off the seam",missing:"ATTACH/DETACH across databases (a second memfs open \u2014 parked until a consumer needs it, matching react-native-sqlite-storage), loadFile, true multi-connection parallelism (single-threaded WASM serializes \u2014 semantically equivalent for SQLite)"}]},"@supersami/rn-foreground-service":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 start rejects; add_task/remove_task/get_task/get_all_tasks accepted; is_running=false",missing:"no Android foreground service in browser"}]},"react-native-azure-auth":{category:"Auth & Payments",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:"load-safe error stub \u2014 authorize rejects",missing:"recommended swap: @azure/msal-browser"}]},"react-native-nitro-device-info":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.5.0",coverage:1,note:'load-safe defaults \u2014 model/manufacturer/deviceId/bundleId/version/buildNumber/systemVersion/systemName all "sootsim"',missing:"consumers should use react-native-device-info (already polyfilled)"}]},"react-native-twilio-video-webrtc":{category:"Networking",stubType:"native",versions:[{range:">=3.0.0",coverage:.55,note:"load-safe noop \u2014 TwilioVideoLocalView/TwilioVideoParticipantView render null; TwilioVideo.connect rejects",missing:"recommended swap: twilio-video web SDK"}]},"@react-native-ml-kit/barcode-scanning":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"native-seam: the BarcodeFormat enum + LINKING_ERROR proxy run from the bundle; the BarcodeScanning native module backs scan() with the native BarcodeDetector API (shipped in the Chromium runtime SootSim runs on \u2014 no vendored library needed), loading the source image through the shared expo-file-system VFS / fetch loader and mapping results to upstream\u2019s exact { format, value } shape with the BarcodeFormat enum values",working:"scan(imageURL) for file:// (VFS) / http(s) / data: images, all BarcodeDetector-supported symbologies mapped to BarcodeFormat (QR/CODE_128/39/93/CODABAR/DATA_MATRIX/EAN/ITF/UPC/PDF417/AZTEC), BarcodeFormat enum",missing:"BarcodeDetector symbology support is browser-implementation-bounded; when unavailable or nothing is detected, resolves [] (a valid no-barcode result, matching the natives) rather than a richer ML Kit bounding-box/cornerPoints payload (upstream Barcode is only { format, value })"}]},"react-native-turbo-mock-location-detector":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 isLocationMocked/isInMockMode=false",missing:"browsers cannot detect mock location"}]},"react-native-xaml":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"Windows-only WinUI/XAML; iOS / Android / web have nothing equivalent"}]},"expo-key-event":{category:"Keyboard",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 addListener/removeListener register but never fire",missing:"consumers can use window keydown/keyup directly on web"}]},"react-native-google-fit":{category:"Health",stubType:"native",versions:[{range:">=0.20.0",coverage:.6,note:"load-safe noop \u2014 authorize reports unavailable; isAuthorized=false; all sample queries return empty",missing:"no Google Fit SDK on iOS / web"}]},"react-native-loader-kit":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:1,note:"load-safe noop \u2014 LoaderKit renders null",missing:"no native loader animations; recommended swap: pure-JS spinner"}]},"@mgcrea/vision-camera-barcode-scanner":{category:"Media",stubType:"native",versions:[{range:">=0.10.0",coverage:.6,note:"load-safe noop \u2014 useBarcodeScanner/useCodeScanner return idle scanner",missing:"paired with react-native-vision-camera (low-coverage upstream); consumers should use jsQR/zxing-js on web"}]},"@stripe/stripe-identity-react-native":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.0.1",coverage:.45,note:"load-safe error stub \u2014 presentVerificationSheet rejects",missing:"no Stripe Identity native flow; recommended swap: Stripe Identity web"}]},"@lottiefiles/dotlottie-react-native":{category:"Animation",stubType:"native",versions:[{range:">=0.5.0",coverage:.55,note:"load-safe noop \u2014 DotLottieAnimation/DotLottiePlayer render null",missing:"no .lottie playback; recommended swap: @lottiefiles/dotlottie-react on web"}]},"react-native-payments":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.10.0",coverage:1,note:"load-safe pass-through \u2014 forwards to globalThis.PaymentRequest where supported",missing:"see @rnw-community/react-native-payments for the modern variant"}]},"@react-native-seoul/naver-login":{category:"Auth & Payments",stubType:"native",versions:[{range:">=3.0.0",coverage:.6,note:"load-safe noop \u2014 initialize/logout/deleteToken accepted; login/getProfile reject",missing:"recommended swap: Naver login JS SDK on web"}]},"@vonovak/react-native-theme-control":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 setNativeAppearance accepted; getNativeAppearance reports system",missing:"sootsim handles colorScheme natively"}]},"@azzapp/react-native-skia-video":{category:"Media",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe noop \u2014 SkiaVideo renders null; VideoComposition class exposed",missing:"no native skia video; recommended swap: <video> + canvas on web"}]},"react-native-ease":{category:"Animation",stubType:"native",versions:[{range:">=0.0.1",coverage:1,note:"load-safe noop \u2014 Easing constants exposed; interpolate returns input",missing:"pure-JS easings live in react-native-reanimated which we polyfill"}]},"react-native-performance-limiter":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 setMode/getMode accepted",missing:"browsers cannot adjust system performance modes"}]},"react-native-bare-kit":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.5.0",coverage:.45,note:"load-safe error stub \u2014 Worklet throws on construction",missing:"no Bare runtime in browser"}]},"react-native-siri-shortcut":{category:"Device & Platform",stubType:"native",versions:[{range:">=4.0.0",coverage:.6,note:"load-safe noop \u2014 donateShortcut/clearAllShortcuts/clearShortcutsWithIdentifiers/presentShortcut accepted; getShortcuts=[]; addEventListener returns removable subscription",missing:"no Siri shortcuts on iOS / web"}]},"react-native-expo-braintree":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.5.0",coverage:.45,note:"load-safe error stub \u2014 runApplePay/runGooglePay/requestPaypalNonce reject",missing:"recommended swap: braintree-web SDK on web"}]},"react-native-pinchable":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe passthrough",missing:"no native pinch-to-zoom; consumers should use sootsim Reanimated GestureHandler"}]},"rn-secure-storage":{category:"Auth & Payments",stubType:"native",versions:[{range:">=3.0.0",coverage:1,note:"partial \u2014 setItem/getItem/remove/exist/multi* backed by localStorage __soot_secure_; getSupportedBiometryType=null",missing:"no real keychain encryption; recommended swap: react-native-keychain (already 0.85)"}]},"@candlefinance/faster-image":{category:"Image",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe noop \u2014 FasterImage renders null",missing:"use expo-image (already polyfilled)"}]},"@azesmway/react-native-unity":{category:"Device & Platform",stubType:"native",versions:[{range:">=0.5.0",coverage:.55,note:"load-safe noop \u2014 UnityView renders null; sendUnityMessage/postMessageToUnity accepted; isReady=false",missing:"no Unity engine in browser; recommended swap: Unity WebGL build embedded in iframe"}]},"@react-native-community/audio-toolkit":{category:"Media",stubType:"native",versions:[{range:">=2.0.0",coverage:.45,note:"load-safe error stub \u2014 Player/Recorder constructors accept; prepare rejects; MediaStates enum exposed",missing:"recommended swap: Web Audio API directly"}]},"@playerdata/react-native-mcu-manager":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.75,note:"load-safe error stub \u2014 McuManager throws on construction",missing:"no MCU/SMP BLE OTA in browser"}]},"react-native-cloud-storage":{category:"Storage & Data",stubType:"native",versions:[{range:">=2.0.0",coverage:.6,note:"load-safe noop \u2014 setValue/delete accepted; getValue=null; isCloudAvailable=false",missing:"no iCloud Drive / Google Drive integration in browser"}]},"react-native-fast-opencv":{category:"ML",stubType:"native",versions:[{range:">=0.4.0",coverage:.45,note:"load-safe error stub \u2014 invoke rejects",missing:"recommended swap: opencv.js"}]},"react-native-ios-modal":{category:"UI Components",stubType:"native",versions:[{range:">=2.0.0",coverage:.55,note:"load-safe passthrough \u2014 iOS modal presentation; sootsim Modal already simulates iOS",missing:"consumers should use sootsim Modal directly"}]},"react-native-aes-gcm-crypto":{category:"Auth & Payments",stubType:"native",versions:[{range:">=0.2.0",coverage:.95,note:"native-seam: real package runs from the bundle (one line \u2014 export default NativeModules.AesGcmCrypto); the AesGcmCrypto native module is backed by Web Crypto SubtleCrypto AES-GCM with exact CryptoKit wire-format parity (base64 key, hex iv/tag, ciphertext/tag split as SealedBox does)",working:"encrypt (utf-8 or base64 plaintext \u2192 {iv, tag, content}), decrypt (\u2192 utf-8 or base64), encryptFile, decryptFile (read/write through the shared expo-file-system VFS so file:// paths round-trip)",missing:"AES-192 keys are browser-dependent under Web Crypto (AES-128/256 always work) \u2014 same caveat as expo-crypto"}]},"react-native-theme-switch-animation":{category:"Animation",stubType:"native",versions:[{range:">=1.0.0",coverage:.7,note:"load-safe noop \u2014 applyTheme resolves immediately; ThemeSwitchAnimationStyle constants exposed",missing:"no native theme transition animation"}]},"@react-native-ml-kit/face-detection":{category:"ML",stubType:"native",versions:[{range:">=1.0.0",coverage:.45,note:"load-safe error stub \u2014 detect rejects",missing:"recommended swap: face-api.js or MediaPipe"}]},"@mhpdev/react-native-haptics":{category:"Device & Platform",stubType:"native",versions:[{range:">=1.0.0",coverage:.85,note:"native-seam: the impact/notification/selection/androidHaptics wrappers run from the bundle; the Haptics TurboModule delegates to SootSim\u2019s shared expo-haptics navigator.vibrate mapping (same enum string values), so behavior is identical to expo-haptics and there is one source of the vibration logic. calls resolve cleanly when no vibrator is present (and the iOS simulator has no haptics hardware either \u2014 the faithful contract)",working:"impact(style: light/medium/heavy/soft/rigid), notification(type: success/warning/error), selection(), androidHaptics() \u2014 all mapped to navigator.vibrate patterns via the shared expo-haptics implementation",missing:"browsers expose only on/off Vibration (no force/sharpness control) \u2014 exact UIFeedbackGenerator texture is approximated by duration, identical to expo-haptics; no perceptible vibration on a device without a vibrator (faithful to the iOS simulator, which has none)"}]},"expo-passkey":{category:"Auth & Payments",stubType:"native",versions:[{range:">=1.0.0",coverage:.6,note:"load-safe noop \u2014 isPasskeyAuthAvailable=false; register/authenticate reject",missing:"no WebAuthn in tenant worker"}]},"react-native-floating-label-input":{category:"UI Components",stubType:"native",versions:[{range:">=1.0.0",coverage:.55,note:"load-safe passthrough",missing:"TextInput is the right primitive"}]},"react-native-share-menu":{category:"Device & Platform",stubType:"native",versions:[{range:">=6.0.0",coverage:.6,note:"load-safe noop \u2014 getInitialShare=null; addNewShareListener returns subscription that never fires",missing:"no iOS Share Extension in browser"}]},"@react-native-ai/apple":{category:"ML",stubType:"native",versions:[{range:">=0.0.1",coverage:.6,note:"load-safe noop \u2014 generateText/generateImage reject; isAvailable=false",missing:"no Apple Intelligence APIs in browser; consumers should use a remote LLM endpoint"}]}},u=new Set(["react-native-firebase","react-native-camera","react-native-ble-plx","react-native-nfc-manager","react-native-health","react-native-in-app-purchase"]);var h=new Set(["react","react-dom","react-native","react-native-web","expo","one","vxrn","tamagui","@tamagui/core","@tamagui/config","typescript","vite","@types/react","@types/react-dom","@react-native-community/cli","@react-native-community/cli-platform-android","@react-native-community/cli-platform-ios","@react-native/babel-preset","@react-native/eslint-config","@react-native/metro-config","@react-native/typescript-config","react-native-typescript-transformer"]);function y(e){return e.one?"one":e.expo?"expo":e["react-native"]?"bare":"unknown"}function b(e){return h.has(e)?!1:e.startsWith("react-native")||e.startsWith("expo-")||e.startsWith("@react-native")||e.startsWith("@shopify/")||e.startsWith("@gorhom/")||e.startsWith("@callstack/")||g[e]!==void 0||u.has(e)}function f(e,l){let m=l.replace(/^[~^>=<\s]+/,"").split("-")[0],[s]=m.split(".").map(Number);for(let i of e.versions){let p=i.range.split(" "),r=!0;for(let t of p){let a=t.match(/^([><=]+)(\d+)/);if(!a)continue;let[,o,c]=a,d=parseInt(c);o===">="&&s<d&&(r=!1),o==="<"&&s>=d&&(r=!1),o===">"&&s<=d&&(r=!1),o==="<="&&s>d&&(r=!1)}if(r)return{coverage:i.coverage,note:i.note}}let n=e.versions[e.versions.length-1];return{coverage:n.coverage*.5,note:`${n.note} (version not explicitly supported)`}}function w(e){let l={...e.dependencies,...e.devDependencies},m=y(l),s=l["react-native"]||null,n=[];for(let[t,a]of Object.entries(l)){if(!b(t))continue;if(u.has(t)){n.push({name:t,version:a,coverage:0,status:"unsupported",note:"requires native SDK"});continue}let o=g[t];if(!o){n.push({name:t,version:a,coverage:.3,status:"auto-stub",note:"auto-stub (basic no-op proxy)"});continue}if(o.stubType==="build-only"){n.push({name:t,version:a,coverage:1,status:"not-relevant",note:"build/config tool \u2014 not imported at runtime"});continue}let c=f(o,a);if(!c){n.push({name:t,version:a,coverage:.3,status:"auto-stub",note:"version not matched"});continue}n.push({name:t,version:a,coverage:c.coverage,status:c.coverage>=.9?"full":"partial",note:c.note})}let i=n.filter(t=>t.status!=="not-relevant"),p=i.length,r=p===0?1:i.reduce((t,a)=>t+a.coverage,0)/p;return{projectName:e.name||"unknown",rnVersion:s,framework:m,packages:n,overallScore:Math.round(r*100)/100}}export{v as COMPAT_CATEGORIES,g as POLYFILL_REGISTRY,u as UNSUPPORTABLE,w as scanDeps};