vybekiit 0.7.26 → 0.7.27

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 (232) hide show
  1. package/dist/bin.js +3891 -1301
  2. package/dist/global-skills/aws-cdk/SKILL.md +19 -5
  3. package/dist/global-skills/aws-cdk/references/fast-deployments.md +191 -0
  4. package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +16 -0
  5. package/dist/global-skills/aws-cloudformation/SKILL.md +16 -26
  6. package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +7 -3
  7. package/dist/global-skills/aws-cloudformation/references/cloudformation-language-server.md +177 -0
  8. package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +8 -2
  9. package/dist/global-skills/aws-cloudformation/references/persist-template-context.script.md +5 -8
  10. package/dist/global-skills/aws-cloudformation/references/retrieve-template-context.script.md +1 -1
  11. package/dist/global-skills/aws-cloudformation/references/security-considerations.md +51 -0
  12. package/dist/global-skills/aws-cloudformation/references/troubleshoot-failed-stack.script.md +138 -0
  13. package/dist/global-skills/aws-cloudformation/references/{validate-cloudformation-template.script.md → validate-with-cfn-lint.script.md} +15 -27
  14. package/dist/global-skills/aws-cloudformation/references/validate-with-cloudformation-validate.script.md +181 -0
  15. package/dist/global-skills/aws-cloudformation/references/validation-tool-selection.md +44 -0
  16. package/dist/global-skills/aws-serverless/SKILL.md +9 -1
  17. package/dist/global-skills/aws-serverless/references/architecture.md +3 -1
  18. package/dist/global-skills/aws-serverless/references/lambda.md +3 -1
  19. package/dist/global-skills/aws-serverless/references/orchestration.md +1 -0
  20. package/dist/global-skills/better-auth-best-practices/SKILL.md +18 -8
  21. package/dist/global-skills/eas-app-stores/SKILL.md +31 -15
  22. package/dist/global-skills/eas-app-stores/agents/openai.yaml +2 -2
  23. package/dist/global-skills/eas-app-stores/references/ios-app-store.md +37 -32
  24. package/dist/global-skills/eas-app-stores/references/native-ios.md +167 -0
  25. package/dist/global-skills/eas-app-stores/references/play-store.md +3 -7
  26. package/dist/global-skills/eas-app-stores/references/testflight.md +39 -35
  27. package/dist/global-skills/eas-simulator/SKILL.md +48 -26
  28. package/dist/global-skills/eas-simulator/references/controllers.md +32 -3
  29. package/dist/global-skills/eas-simulator/references/run-your-app.md +34 -4
  30. package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -4
  31. package/dist/global-skills/eas-update/SKILL.md +146 -0
  32. package/dist/global-skills/eas-update/agents/openai.yaml +4 -0
  33. package/dist/global-skills/expo-animation/RECIPES.md +2 -2
  34. package/dist/global-skills/expo-animation/SKILL.md +9 -2
  35. package/dist/global-skills/expo-brownfield/SKILL.md +18 -11
  36. package/dist/global-skills/expo-brownfield/agents/openai.yaml +2 -2
  37. package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +94 -69
  38. package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +40 -42
  39. package/dist/global-skills/expo-brownfield/references/comparison.md +5 -5
  40. package/dist/global-skills/expo-brownfield/references/feature-integration.md +163 -0
  41. package/dist/global-skills/expo-brownfield/references/troubleshooting.md +17 -17
  42. package/dist/global-skills/expo-brownfield/references/version-compatibility.md +40 -0
  43. package/dist/global-skills/expo-data-fetching/SKILL.md +27 -6
  44. package/dist/global-skills/expo-design-system/SKILL.md +27 -7
  45. package/dist/global-skills/expo-design-system/references/audit.md +7 -2
  46. package/dist/global-skills/expo-design-system/references/native-slop.md +74 -0
  47. package/dist/global-skills/expo-examples/SKILL.md +0 -1
  48. package/dist/global-skills/expo-examples/references/catalog.md +1 -1
  49. package/dist/global-skills/expo-migrate-module/SKILL.md +21 -10
  50. package/dist/global-skills/expo-migrate-module/references/compatibility.md +80 -23
  51. package/dist/global-skills/expo-migrate-module/references/migration-map.md +162 -11
  52. package/dist/global-skills/expo-native-ui/SKILL.md +25 -16
  53. package/dist/global-skills/expo-native-ui/agents/openai.yaml +2 -2
  54. package/dist/global-skills/expo-native-ui/references/controls.md +5 -46
  55. package/dist/global-skills/expo-native-ui/references/icons.md +21 -2
  56. package/dist/global-skills/expo-native-ui/references/media.md +15 -20
  57. package/dist/global-skills/expo-native-ui/references/visual-effects.md +12 -11
  58. package/dist/global-skills/expo-overview/SKILL.md +17 -12
  59. package/dist/global-skills/expo-router/SKILL.md +5 -3
  60. package/dist/global-skills/expo-router/references/tabs.md +5 -5
  61. package/dist/global-skills/expo-upgrade/SKILL.md +3 -1
  62. package/dist/global-skills/expo-web-to-native/references/false-friends.md +2 -2
  63. package/dist/global-skills/expo-web-to-native/references/native-patterns.md +1 -1
  64. package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +13 -16
  65. package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +4 -5
  66. package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +4 -4
  67. package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +3 -3
  68. package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
  69. package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +4 -5
  70. package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +3 -3
  71. package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +24 -25
  72. package/dist/global-skills/firebase-auth-basics/references/security_rules.md +4 -2
  73. package/dist/global-skills/firebase-crashlytics/references/android_setup.md +7 -4
  74. package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +2 -3
  75. package/dist/global-skills/firebase-data-connect/SKILL.md +2 -1
  76. package/dist/global-skills/firebase-data-connect/examples.md +4 -4
  77. package/dist/global-skills/firebase-data-connect/reference/config.md +5 -4
  78. package/dist/global-skills/firebase-data-connect/reference/realtime.md +1 -2
  79. package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +2 -2
  80. package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +2 -2
  81. package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +17 -6
  82. package/dist/global-skills/firebase-data-connect/reference/security.md +5 -5
  83. package/dist/global-skills/firebase-data-connect/templates.md +2 -1
  84. package/dist/global-skills/firebase-firestore/SKILL.md +20 -8
  85. package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +5 -4
  86. package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +12 -3
  87. package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +16 -18
  88. package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +1 -1
  89. package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +5 -1
  90. package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +7 -7
  91. package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +5 -5
  92. package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +4 -4
  93. package/dist/global-skills/firebase-firestore/references/standard/indexes.md +16 -18
  94. package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +1 -1
  95. package/dist/global-skills/firebase-remote-config-basics/SKILL.md +0 -5
  96. package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +36 -8
  97. package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +1 -7
  98. package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +17 -6
  99. package/dist/global-skills/{firebase-firestore/references/standard/security_rules.md → firestore-rules-creation/SKILL.md} +24 -13
  100. package/dist/global-skills/grow-my-customers/SKILL.md +23 -0
  101. package/dist/global-skills/instrument-feature-flags/SKILL.md +25 -25
  102. package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +141 -285
  103. package/dist/global-skills/instrument-feature-flags/references/android.md +6 -15
  104. package/dist/global-skills/instrument-feature-flags/references/api.md +4 -11
  105. package/dist/global-skills/instrument-feature-flags/references/best-practices.md +1 -13
  106. package/dist/global-skills/instrument-feature-flags/references/django.md +14 -27
  107. package/dist/global-skills/instrument-feature-flags/references/dotnet.md +20 -79
  108. package/dist/global-skills/instrument-feature-flags/references/elixir.md +1 -9
  109. package/dist/global-skills/instrument-feature-flags/references/flask.md +13 -13
  110. package/dist/global-skills/instrument-feature-flags/references/flutter.md +3 -24
  111. package/dist/global-skills/instrument-feature-flags/references/go.md +3 -15
  112. package/dist/global-skills/instrument-feature-flags/references/ios.md +4 -17
  113. package/dist/global-skills/instrument-feature-flags/references/java.md +5 -13
  114. package/dist/global-skills/instrument-feature-flags/references/laravel.md +13 -17
  115. package/dist/global-skills/instrument-feature-flags/references/next-js.md +25 -32
  116. package/dist/global-skills/instrument-feature-flags/references/nodejs.md +8 -15
  117. package/dist/global-skills/instrument-feature-flags/references/php.md +1 -15
  118. package/dist/global-skills/instrument-feature-flags/references/python.md +2 -15
  119. package/dist/global-skills/instrument-feature-flags/references/react-native.md +13 -15
  120. package/dist/global-skills/instrument-feature-flags/references/react.md +17 -21
  121. package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +37 -83
  122. package/dist/global-skills/instrument-feature-flags/references/ruby.md +2 -15
  123. package/dist/global-skills/instrument-feature-flags/references/rust.md +13 -25
  124. package/dist/global-skills/instrument-feature-flags/references/usage.md +14 -63
  125. package/dist/global-skills/instrument-feature-flags/references/web.md +9 -14
  126. package/dist/global-skills/instrument-product-analytics/SKILL.md +29 -29
  127. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +3 -1
  128. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +3 -1
  129. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +3 -1
  130. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +3 -1
  131. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +3 -1
  132. package/dist/global-skills/instrument-product-analytics/references/android.md +72 -107
  133. package/dist/global-skills/instrument-product-analytics/references/angular.md +26 -28
  134. package/dist/global-skills/instrument-product-analytics/references/astro.md +13 -24
  135. package/dist/global-skills/instrument-product-analytics/references/configuration.md +45 -63
  136. package/dist/global-skills/instrument-product-analytics/references/django.md +14 -27
  137. package/dist/global-skills/instrument-product-analytics/references/dotnet.md +20 -79
  138. package/dist/global-skills/instrument-product-analytics/references/elixir.md +47 -49
  139. package/dist/global-skills/instrument-product-analytics/references/flask.md +13 -13
  140. package/dist/global-skills/instrument-product-analytics/references/flutter.md +60 -90
  141. package/dist/global-skills/instrument-product-analytics/references/go.md +17 -56
  142. package/dist/global-skills/instrument-product-analytics/references/identify-users.md +15 -15
  143. package/dist/global-skills/instrument-product-analytics/references/ios.md +11 -15
  144. package/dist/global-skills/instrument-product-analytics/references/laravel.md +13 -17
  145. package/dist/global-skills/instrument-product-analytics/references/next-js.md +25 -32
  146. package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +13 -27
  147. package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +14 -28
  148. package/dist/global-skills/instrument-product-analytics/references/php.md +33 -84
  149. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +229 -9
  150. package/dist/global-skills/instrument-product-analytics/references/python.md +415 -106
  151. package/dist/global-skills/instrument-product-analytics/references/react-native.md +161 -155
  152. package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +12 -33
  153. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +15 -33
  154. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +12 -33
  155. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +26 -41
  156. package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +37 -83
  157. package/dist/global-skills/instrument-product-analytics/references/ruby.md +48 -108
  158. package/dist/global-skills/instrument-product-analytics/references/svelte.md +18 -24
  159. package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +17 -19
  160. package/dist/global-skills/instrument-product-analytics/references/usage.md +14 -63
  161. package/dist/global-skills/instrument-product-analytics/references/vue-js.md +29 -28
  162. package/dist/global-skills/manifest.json +8 -2
  163. package/dist/global-skills/mongodb-search-and-ai/SKILL.md +28 -37
  164. package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +438 -0
  165. package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +60 -4
  166. package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +46 -108
  167. package/dist/global-skills/neon/SKILL.md +207 -213
  168. package/dist/global-skills/neon/references/auth.md +12 -0
  169. package/dist/global-skills/neon/references/claimable-neon.md +10 -14
  170. package/dist/global-skills/neon/references/function-triggers.md +53 -0
  171. package/dist/global-skills/neon/references/logs-loki.md +61 -0
  172. package/dist/global-skills/neon/references/parse-env.md +32 -0
  173. package/dist/global-skills/neon/references/sdk.md +7 -0
  174. package/dist/global-skills/neon-ai-gateway/SKILL.md +14 -16
  175. package/dist/global-skills/neon-auth/SKILL.md +155 -0
  176. package/dist/global-skills/neon-auth/references/managed-auth.md +173 -0
  177. package/dist/global-skills/neon-auth/references/self-managed.md +25 -0
  178. package/dist/global-skills/neon-functions/SKILL.md +159 -84
  179. package/dist/global-skills/neon-functions/references/ai-sdk.md +4 -6
  180. package/dist/global-skills/neon-functions/references/function-triggers.md +249 -0
  181. package/dist/global-skills/neon-functions/references/mastra-studio.md +3 -3
  182. package/dist/global-skills/neon-functions/references/mcp.md +1 -1
  183. package/dist/global-skills/neon-functions/references/production-hardening.md +340 -0
  184. package/dist/global-skills/neon-functions/references/sse.md +8 -5
  185. package/dist/global-skills/neon-object-storage/SKILL.md +10 -11
  186. package/dist/global-skills/neon-postgres/SKILL.md +120 -17
  187. package/dist/global-skills/neon-postgres/references/full-text-search.md +99 -0
  188. package/dist/global-skills/neon-postgres/references/hybrid-search.md +90 -0
  189. package/dist/global-skills/neon-postgres/references/lakebase-search-drizzle.md +172 -0
  190. package/dist/global-skills/neon-postgres/references/vector-search.md +137 -0
  191. package/dist/global-skills/neon-postgres-branches/SKILL.md +3 -3
  192. package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -1
  193. package/dist/global-skills/onboarding/SKILL.md +8 -6
  194. package/dist/global-skills/resend/SKILL.md +4 -2
  195. package/dist/global-skills/resend/references/broadcasts.md +6 -1
  196. package/dist/global-skills/resend/references/receiving.md +29 -10
  197. package/dist/global-skills/resend/references/sending/email-management.md +14 -4
  198. package/dist/global-skills/resend/references/topics.md +9 -6
  199. package/dist/global-skills/resend/references/usage.md +117 -0
  200. package/dist/global-skills/resend/references/webhooks.md +59 -2
  201. package/dist/global-skills/stripe-best-practices/SKILL.md +35 -29
  202. package/dist/global-skills/stripe-best-practices/references/billing.md +9 -2
  203. package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
  204. package/dist/global-skills/stripe-best-practices/references/security.md +3 -1
  205. package/dist/global-skills/stripe-best-practices/references/tax.md +39 -20
  206. package/dist/global-skills/supabase/SKILL.md +6 -0
  207. package/dist/global-skills/use-railway/SKILL.md +42 -22
  208. package/dist/global-skills/use-railway/references/analyze-db.md +7 -6
  209. package/dist/global-skills/use-railway/references/cloud-agents.md +70 -0
  210. package/dist/global-skills/use-railway/references/configure.md +17 -2
  211. package/dist/global-skills/use-railway/references/databases.md +107 -0
  212. package/dist/global-skills/use-railway/references/deploy.md +5 -5
  213. package/dist/global-skills/use-railway/references/feature-flags.md +25 -13
  214. package/dist/global-skills/use-railway/references/iac.md +66 -77
  215. package/dist/global-skills/use-railway/references/operate.md +26 -3
  216. package/dist/global-skills/use-railway/references/request.md +31 -23
  217. package/dist/global-skills/use-railway/references/setup.md +16 -5
  218. package/dist/global-skills/use-railway/references/tracing.md +261 -0
  219. package/dist/global-skills/use-railway/references/usage.md +52 -0
  220. package/dist/global-skills/validate-my-idea/SKILL.md +54 -0
  221. package/dist/global-skills/{feedback → vybekiit-feedback}/SKILL.md +16 -12
  222. package/dist/global-skills/watch-my-app/SKILL.md +53 -0
  223. package/dist/global-skills/workers-best-practices/SKILL.md +36 -103
  224. package/dist/global-skills/workers-best-practices/references/configuration.md +139 -0
  225. package/dist/global-skills/workers-best-practices/references/platform-apis.md +51 -0
  226. package/dist/global-skills/workers-best-practices/references/{rules.md → runtime-patterns.md} +13 -137
  227. package/dist/global-skills/wrangler/SKILL.md +48 -901
  228. package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +19 -15
  229. package/package.json +9 -8
  230. package/dist/global-skills/expo-native-ui/references/animations.md +0 -220
  231. package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +0 -577
  232. package/dist/global-skills/workers-best-practices/references/review.md +0 -174
@@ -89,7 +89,7 @@ function rubberband(overshoot, dimension, constant = 0.55) {
89
89
  Every pressable in the app. This passes the frequency gate only because it's near-imperceptible: 120ms and a 3% scale is the ceiling for something touched this often — anything longer or larger belongs to rarer moments, per step 1 in SKILL.md. No gesture, no shared value — a CSS transition is the whole implementation.
90
90
 
91
91
  ```jsx
92
- import Animated from 'react-native-reanimated';
92
+ import Animated, { cubicBezier } from 'react-native-reanimated';
93
93
  import { Pressable, StyleSheet } from 'react-native';
94
94
 
95
95
  function PressableScale({ onPress, children }) {
@@ -112,7 +112,7 @@ const styles = StyleSheet.create({
112
112
  transform: [{ scale: 1 }],
113
113
  transitionProperty: 'transform',
114
114
  transitionDuration: '120ms',
115
- transitionTimingFunction: 'cubic-bezier(0.23, 1, 0.32, 1)',
115
+ transitionTimingFunction: cubicBezier(0.23, 1, 0.32, 1),
116
116
  },
117
117
  pressed: { transform: [{ scale: 0.97 }] },
118
118
  });
@@ -126,13 +126,19 @@ Reanimated's spring takes Apple's two designer parameters directly — use this
126
126
  **Never `ease-in` on UI.** It starts slow, delaying the exact moment the user is watching. Reanimated's built-ins are as weak as CSS's — use these:
127
127
 
128
128
  ```js
129
- import { Easing } from 'react-native-reanimated';
129
+ import { cubicBezier, Easing } from 'react-native-reanimated';
130
130
 
131
+ // transitionTimingFunction / animationTimingFunction
132
+ const CSS_EASE_OUT = cubicBezier(0.23, 1, 0.32, 1);
133
+
134
+ // withTiming / .easing(...)
131
135
  const EASE_OUT = Easing.bezier(0.23, 1, 0.32, 1); // strong ease-out for UI
132
136
  const EASE_IN_OUT = Easing.bezier(0.77, 0, 0.175, 1); // on-screen movement
133
137
  const EASE_SHEET = Easing.bezier(0.32, 0.72, 0, 1); // iOS sheet curve
134
138
  ```
135
139
 
140
+ Reanimated 4.1.1 and 4.5.1 reject raw `'cubic-bezier(...)'` strings. CSS transitions and animations use `cubicBezier(...)`; `withTiming` and `.easing(...)` use `Easing.bezier(...)`.
141
+
136
142
  **Duration:**
137
143
 
138
144
  | Element | Duration |
@@ -159,7 +165,7 @@ This is the mobile-specific craft, and it's where most React Native motion dies.
159
165
  Every hover affordance from the web has to be redesigned, not ported.
160
166
 
161
167
  - **Feedback on press-in, commit on press-out.** Waiting for the tap to complete before showing anything feels dead — this is the latency the user actually perceives.
162
- - **`scale: 0.97` in 100–150ms** on any pressable, `Pressable` + a CSS transition. `scale` takes the label and icons with it, which is what makes it read as physical.
168
+ - **`scale: 0.97` in 100–150ms** on any button-like pressable, `Pressable` + a CSS transition. `scale` takes the label and icons with it, which is what makes it read as physical. Full-width list rows are the exception: they highlight their background instead — a scaling row reads as the whole screen squishing.
163
169
  - **44×44pt minimum touch target** (48dp Android). If the visual is smaller, add `hitSlop` — don't grow the visual.
164
170
  - **`pressRetentionOffset`** so a finger drifting a few pixels doesn't cancel a press the user meant.
165
171
  - **Android ripple only in a Material-styled app.** In a custom-designed app, the same scale on both platforms is more coherent than a ripple on one.
@@ -238,6 +244,7 @@ For ready-to-build implementations — press feedback, drag-to-dismiss sheet, sw
238
244
  | A screen transition rebuilt in JS | native stack `animation` |
239
245
  | Sliding between tabs | `animation: 'none'` |
240
246
  | `Easing.in(...)` on a UI element | `Easing.bezier(0.23, 1, 0.32, 1)` |
247
+ | `'cubic-bezier(...)'` in a Reanimated CSS style | `cubicBezier(...)` from `react-native-reanimated` |
241
248
  | `scale(0)` entrance | `scale(0.95)` + `opacity: 0` |
242
249
  | Distance-only dismissal threshold | velocity **or** distance — a flick is enough |
243
250
  | Hard stop at a boundary | rubber-band resistance |
@@ -1,12 +1,18 @@
1
1
  ---
2
2
  name: expo-brownfield
3
- description: Framework (OSS). Integrate Expo and React Native into an existing native iOS or Android app. Use when the user mentions brownfield, embedding React Native in a native app, AAR/XCFramework, or adding Expo to an existing Kotlin/Swift project. Covers both the isolated approach and the integrated approach.
3
+ description: Framework (OSS). Integrate Expo and React Native into an existing native iOS or Android app. Use for brownfield, embedding a React Native screen in SwiftUI/UIKit or Kotlin, or AAR/XCFramework packaging. Covers isolated and integrated approaches. For building or distributing a purely native app with EAS, use eas-app-stores.
4
4
  ---
5
5
 
6
6
  # Expo Brownfield
7
7
 
8
8
  A **brownfield** app is an existing native iOS or Android app that adopts React Native incrementally, as opposed to a **greenfield** app that is React Native from day one.
9
9
 
10
+ ## Inspect the host first
11
+
12
+ Identify the existing app entry point, navigation owner, native build system, deployment targets, and any React Native runtime already linked. Record the installed Expo, React Native, and brownfield package versions from the lockfile. Adding EAS Build or Submit to a Swift app alone does not require React Native; route that task to `eas-app-stores`.
13
+
14
+ Preserve the host's SwiftUI `App` / UIKit window and native screens when embedding a feature. **Do not run prebuild in a manually maintained native host**, including during troubleshooting. An isolated Expo producer may use CNG; keep its generated `ios/` and `android/` separate from the consuming app.
15
+
10
16
  Expo supports two distinct ways to add React Native to a brownfield project:
11
17
 
12
18
  | Approach | What ships to the native app | When to choose |
@@ -23,12 +29,13 @@ Use these quick rules — fall through to `comparison.md` for anything ambiguous
23
29
  - **Choose isolated** if the iOS/Android team must consume RN as a regular library dependency (AAR or XCFramework), without installing Node, Yarn, or the React Native build toolchain.
24
30
  - **Choose isolated** if RN code and native code live in separate repositories or release on independent cadences.
25
31
  - **Choose integrated** if a single team owns both the native and RN code and is willing to add React Native + Expo to the native project's Gradle and CocoaPods setup.
26
- - **Choose integrated** if you want hot reload and JS source maps to work seamlessly inside the existing native build process.
32
+ - Both approaches support Metro and Fast Refresh in Debug. Choose integrated for shared build ownership, not because isolated lacks live JS iteration.
27
33
 
28
34
  ## References
29
35
 
30
36
  - ./references/brownfield-isolated.md -- Build RN as AAR/XCFramework and consume from the native app (BrownfieldActivity, ReactNativeViewController, ReactNativeView)
31
- - ./references/brownfield-integrated.md -- Add RN and Expo directly to existing Gradle and CocoaPods builds (ReactActivity, RCTRootView, Podfile)
37
+ - ./references/brownfield-integrated.md -- Add RN and Expo directly to existing Gradle and CocoaPods builds, preserving the native app shell
38
+ - ./references/feature-integration.md -- Pass input, return results, dismiss, clean up listeners, and forward lifecycle events; includes a SwiftUI host example
32
39
  - ./references/comparison.md -- Decision criteria, trade-offs, and scenario mapping for choosing an approach
33
40
  - ./references/troubleshooting.md -- Metro connection, build, signing, and module-resolution issues common to both approaches
34
41
 
@@ -39,19 +46,19 @@ More information available at https://docs.expo.dev/brownfield/overview/
39
46
  Both approaches require, in the environment that _builds_ the React Native side:
40
47
 
41
48
  - **Node.js (LTS)** — runs the Expo CLI and JavaScript code.
42
- - **Yarn** — manages JavaScript dependencies.
49
+ - The project's package manager and lockfile — npm, Yarn, pnpm, or Bun. Do not switch package managers just to follow an example.
43
50
 
44
- The integrated approach additionally requires **CocoaPods** on iOS (`sudo gem install cocoapods`). The isolated approach does **not** require CocoaPods or any RN tooling in the consuming native app.
51
+ The iOS build environment needs Xcode and CocoaPods (use the project's Gemfile/Bundler setup when present). The isolated consuming app needs Xcode but no CocoaPods or RN tooling just to consume the artifacts.
45
52
 
46
- ## Versioning note
53
+ ## Select compatible versions
47
54
 
48
- **Expo SDK 55 is the minimum supported version for brownfield integration.** Earlier SDKs lack `expo-brownfield`, the required `ExpoReactHostFactory` / `ExpoReactNativeFactory` entry points, and the current autolinking surface. When creating the Expo project, always pin the SDK explicitly:
55
+ For an existing Expo/RN project, keep its selected SDK and use `npx expo install` to align dependencies. Do not upgrade it just to follow this skill. For a new producer, use the **current stable SDK** compatible with the host's OS support, dependencies, and build toolchain; confirm the release is stable before selecting it.
49
56
 
50
- ```sh
51
- npx create-expo-app@latest my-project --template default@sdk-55
52
- ```
57
+ Before native setup, read [./references/version-compatibility.md](./references/version-compatibility.md) for matching native templates, toolchain/OS requirements, and build defaults across SDK versions. A purely native consumer has no Expo SDK version to pin, but must satisfy the artifact's requirements.
58
+
59
+ ## Verify the feature in the host
53
60
 
54
- Pin the same Expo SDK across both the RN project and any embedded dependencies.
61
+ Open the RN screen with input, return a result to native, dismiss, and reopen with fresh input. Check listener cleanup and the host's original navigation. Then build the host in Release with a Release artifact and Metro stopped. Rendering only in Expo Go or the producer's example app does not validate the integration. See [./references/feature-integration.md](./references/feature-integration.md) for the complete acceptance scenario.
55
62
 
56
63
  ## Submitting Feedback
57
64
  If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: "Expo Brownfield"
3
- short_description: "Integrate Expo and React Native into existing native iOS or Android apps"
4
- default_prompt: "Use $expo-brownfield when adding Expo or React Native to an existing native app, choosing isolated vs integrated brownfield architecture, embedding AAR/XCFramework outputs, wiring Gradle or CocoaPods, and troubleshooting native integration issues."
3
+ short_description: "Embed Expo screens in existing native iOS and Android apps"
4
+ default_prompt: "Use $expo-brownfield when adding Expo or React Native to an existing native app, choosing isolated vs integrated brownfield architecture, embedding SwiftUI/UIKit screens or AAR/XCFramework outputs, wiring Gradle or CocoaPods, and troubleshooting native integration issues."
@@ -6,39 +6,35 @@ Add React Native and Expo directly to the existing native project's build system
6
6
 
7
7
  - A single team owns both the native and React Native code.
8
8
  - The team is comfortable adding React Native and Expo to the native build (Gradle plugin, CocoaPods pods).
9
- - You want hot reload, JS source maps, and a single Metro instance to "just work" inside the existing build.
9
+ - You want JS bundling and native compilation in the host's existing build pipeline. Both approaches support Metro during development.
10
10
  - You prefer one repository and one build pipeline over shipping a prebuilt artifact.
11
11
 
12
12
  If the native team must not need Node, Yarn, or React Native tooling, use [./brownfield-isolated.md](./brownfield-isolated.md) instead.
13
13
 
14
14
  ## Prerequisites
15
15
 
16
- - **Expo SDK 54 or later** — the `ExpoReactHostFactory`, `ExpoReactNativeFactory`, and `ApplicationLifecycleDispatcher` entry points used below require SDK 54+. Earlier SDKs do not support this setup.
16
+ - **An Expo/React Native version pair compatible with the host** — check [version compatibility](./version-compatibility.md) before editing the host. Use the selected SDK's native template and installed APIs; do not infer the minimum version of integrated brownfield from the separate `expo-brownfield` package.
17
17
  - **Node.js (LTS)** — runs JavaScript and the Expo CLI.
18
- - **Yarn** — manages JavaScript dependencies.
19
- - **CocoaPods** (iOS) — `sudo gem install cocoapods`.
18
+ - The existing package manager and lockfile (commands below use Yarn as an example).
19
+ - **Xcode and CocoaPods** (iOS) — use the host's Gemfile/Bundler setup when available.
20
20
 
21
21
  ---
22
22
 
23
23
  ## 1) Create an Expo project
24
24
 
25
- Create the Expo project inside (or alongside) the existing native project. **Pin to SDK 55 or later — earlier SDKs do not support brownfield integration:**
25
+ Create the Expo project inside or alongside the existing native project, using the SDK selected during host inspection. For a new small feature on the current stable SDK:
26
26
 
27
27
  ```sh
28
- npx create-expo-app@latest my-project --template default@sdk-55
28
+ npx create-expo-app@latest my-project --template blank@latest
29
29
  ```
30
30
 
31
- The new project ships a TypeScript example app. The JS entry point registers a root component under the name `"main"` — this name must match the `moduleName` referenced from the native side later.
31
+ For TypeScript, install `typescript` and `@types/react` with `npx expo install`, then use the explicit entry point in [feature integration](./feature-integration.md#register-the-component-that-receives-input). The JS entry point registers a root component under the name `"main"` — this name must match the `moduleName` referenced from the native side later.
32
32
 
33
- ## 2) Place native projects under the Expo project
33
+ ## 2) Establish the project layout
34
34
 
35
- A standard React Native project keeps native code under `android/` and `ios/`. Move the existing native projects in:
35
+ Keep the existing repository layout when possible and configure paths explicitly. If consolidating into an Expo root, the resulting native build roots should be `my-project/ios/<Host>.xcodeproj` and `my-project/android/settings.gradle`, not an extra nested `android/android-project/` directory. Preserve source files, targets, signing, schemes, and relative resource paths; verify the native host still builds after relocation.
36
36
 
37
- ```sh
38
- mkdir my-project/android
39
- mv /path/to/your/android-project my-project/android/
40
- # repeat for ios/
41
- ```
37
+ Ensure hand-maintained `ios/` and `android/` files are tracked and included in any EAS upload. A create-expo-app `.gitignore` may exclude them by default. **Do not run prebuild on this host.** Apply native configuration and SDK upgrade diffs directly.
42
38
 
43
39
  ### Monorepo alternative
44
40
 
@@ -62,7 +58,7 @@ Run `yarn install` at the root. This installs `node_modules` at the workspace ro
62
58
 
63
59
  ### `settings.gradle`
64
60
 
65
- Register the React Native Gradle plugin and Expo autolinking. Reference: [bare-minimum template `settings.gradle`](https://github.com/expo/expo/blob/main/templates/expo-template-bare-minimum/android/settings.gradle).
61
+ Register the React Native Gradle plugin and Expo autolinking. Reference: [bare-minimum template `settings.gradle`](https://github.com/expo/expo/blob/sdk-57/templates/expo-template-bare-minimum/android/settings.gradle).
66
62
 
67
63
  ```groovy
68
64
  pluginManagement {
@@ -130,7 +126,7 @@ apply plugin: "com.facebook.react.rootproject"
130
126
 
131
127
  ### `app/build.gradle`
132
128
 
133
- Apply the React Native plugin and configure the `react { ... }` block. The full template is at [bare-minimum `app/build.gradle`](https://github.com/expo/expo/blob/main/templates/expo-template-bare-minimum/android/app/build.gradle); the minimum that must change in your existing module:
129
+ Apply the React Native plugin and configure the `react { ... }` block. The full template is at [bare-minimum `app/build.gradle`](https://github.com/expo/expo/blob/sdk-57/templates/expo-template-bare-minimum/android/app/build.gradle); the minimum that must change in your existing module:
134
130
 
135
131
  ```groovy
136
132
  apply plugin: "com.android.application"
@@ -142,6 +138,7 @@ def projectRoot = rootDir.getAbsoluteFile().getParentFile().getAbsolutePath()
142
138
  react {
143
139
  entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", projectRoot, "android", "absolute"].execute(null, rootDir).text.trim())
144
140
  reactNativeDir = new File(["node", "--print", "require.resolve('react-native/package.json')"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
141
+ hermesCommand = new File(["node", "--print", "require.resolve('hermes-compiler/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsolutePath() + "/hermesc/%OS-BIN%/hermesc"
145
142
  codegenDir = new File(["node", "--print", "require.resolve('@react-native/codegen/package.json', { paths: [require.resolve('react-native/package.json')] })"].execute(null, rootDir).text.trim()).getParentFile().getAbsoluteFile()
146
143
  cliFile = new File(["node", "--print", "require.resolve('@expo/cli', { paths: [require.resolve('expo/package.json')] })"].execute(null, rootDir).text.trim())
147
144
  bundleCommand = "export:embed"
@@ -149,6 +146,8 @@ react {
149
146
  }
150
147
  ```
151
148
 
149
+ The Hermes compiler resolution above follows SDK 57; use the selected SDK's template for other versions.
150
+
152
151
  > **Monorepo:** set `root = file("../../")` (or wherever your Expo project lives) inside the `react { ... }` block.
153
152
 
154
153
  ### `gradle.properties`
@@ -279,7 +278,7 @@ The integrated approach drives iOS through CocoaPods + Expo modules autolinking,
279
278
 
280
279
  ### `ios/Podfile`
281
280
 
282
- Create (or update) `ios/Podfile` based on the [bare-minimum Podfile](https://github.com/expo/expo/blob/main/templates/expo-template-bare-minimum/ios/Podfile). The essential lines:
281
+ Create (or update) `ios/Podfile` based on the [bare-minimum Podfile](https://github.com/expo/expo/blob/sdk-57/templates/expo-template-bare-minimum/ios/Podfile). The following excerpt follows SDK 57. For another SDK, adapt its matching template; preserve the host's other targets and Podfile hooks:
283
282
 
284
283
  ```ruby
285
284
  require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking")
@@ -288,6 +287,13 @@ require File.join(File.dirname(`node --print "require.resolve('react-native/pack
288
287
  require 'json'
289
288
  podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
290
289
 
290
+ ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] ||= podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR']
291
+ ENV['RCT_USE_RN_DEP'] ||= podfile_properties['ios.buildReactNativeFromSource'] == 'true' ? '0' : '1'
292
+ ENV['RCT_USE_PREBUILT_RNCORE'] ||= podfile_properties['ios.buildReactNativeFromSource'] == 'true' ? '0' : '1'
293
+ ENV['RCT_HERMES_V1_ENABLED'] ||= '0' if podfile_properties['expo.useHermesV1'] == 'false'
294
+ ENV['EXPO_USE_PRECOMPILED_MODULES'] = '0' if podfile_properties['EXPO_USE_PRECOMPILED_MODULES'] == 'false'
295
+ ENV['EXPO_USE_PRECOMPILED_MODULES'] ||= '1'
296
+
291
297
  platform :ios, podfile_properties['ios.deploymentTarget'] || '16.4'
292
298
 
293
299
  prepare_react_native_project!
@@ -324,7 +330,7 @@ target 'MyApp' do
324
330
  end
325
331
  ```
326
332
 
327
- Replace `'MyApp'` with the existing Xcode target name. The `:app_path` value tells `use_react_native!` where the JS app lives — set it to the absolute path of your Expo project root if you are in a monorepo.
333
+ The `16.4` fallback and prebuilt settings match the SDK 57 template; retain a higher host/module requirement and use the selected SDK's minimum for other versions. Replace `'MyApp'` with the existing Xcode target name. The `:app_path` value tells `use_react_native!` where the JS app lives — set it to the absolute path of your Expo project root if you are in a monorepo.
328
334
 
329
335
  Create `ios/Podfile.properties.json` alongside the Podfile (defaults are fine):
330
336
 
@@ -345,7 +351,9 @@ Open the generated `.xcworkspace` (not the `.xcodeproj`) from now on.
345
351
 
346
352
  ### Xcode project changes
347
353
 
348
- Three Xcode-side adjustments are required before the app can build and run a React Native screen. Skip any one and either CocoaPods scripts fail under sandboxing, the JS bundle never lands in the IPA (release crashes looking for `main.jsbundle`), or the status bar fights React Native at runtime.
354
+ Merge these settings into the existing target. Compare against the native template for the selected SDK rather than copying the moving `main` template wholesale.
355
+
356
+ Configure script execution and Release bundling, then reconcile status-bar ownership with the native host.
349
357
 
350
358
  #### 1. Disable user script sandboxing
351
359
 
@@ -356,6 +364,8 @@ In Xcode, select your project → app target → **Build Settings**, search for
356
364
  On the app target's **Build Phases** tab, add a new **Run Script** phase **before** `[CP] Embed Pods Frameworks`. This phase bundles JS for release builds and is skipped automatically in debug (Metro serves the bundle then).
357
365
 
358
366
  ```sh
367
+ # Configure NODE_BINARY in ios/.xcode.env for the machine running Xcode.
368
+ # For example: export NODE_BINARY=$(command -v node)
359
369
  if [[ -f "$PODS_ROOT/../.xcode.env" ]]; then
360
370
  source "$PODS_ROOT/../.xcode.env"
361
371
  fi
@@ -394,48 +404,35 @@ This script writes `main.jsbundle` into the app's resources directory in release
394
404
 
395
405
  #### 3. Update `Info.plist`
396
406
 
397
- Set `UIViewControllerBasedStatusBarAppearance` to `NO` so React Native can manage the status bar:
407
+ Expo templates set `UIViewControllerBasedStatusBarAppearance` to `NO` for React Native status-bar control. This is an app-wide setting: preserve the host's existing controller-based behavior when required, and adapt the embedded screen's status-bar handling. If the host adopts the template behavior, use:
398
408
 
399
409
  ```xml
400
410
  <key>UIViewControllerBasedStatusBarAppearance</key>
401
411
  <false/>
402
412
  ```
403
413
 
404
- ### `AppDelegate.swift`
414
+ ### Own the runtime without replacing the native window
405
415
 
406
- Wire React Native into the app delegate via Expo's `ExpoReactNativeFactory`. The delegate's `bundleURL()` selects the Metro dev server in `DEBUG` and the embedded bundle in release.
416
+ Keep the existing `AppDelegate`, `SceneDelegate`, SwiftUI `App`, and navigation stack. Add one retained runtime owner and pass it to RN screens. This keeps the factory and its delegate alive across presentations without creating a competing `@main` or a new root window.
407
417
 
408
418
  ```swift
419
+ import UIKit
409
420
  internal import Expo
410
421
  import React
411
422
  import ReactAppDependencyProvider
412
423
 
413
- @main
414
- class AppDelegate: ExpoAppDelegate {
415
- var window: UIWindow?
424
+ @MainActor
425
+ final class ReactNativeRuntime {
426
+ private let delegate: ReactNativeDelegate
427
+ let factory: ExpoReactNativeFactory
428
+ let launchOptions: [UIApplication.LaunchOptionsKey: Any]?
416
429
 
417
- var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
418
- var reactNativeFactory: RCTReactNativeFactory?
419
-
420
- public override func application(
421
- _ application: UIApplication,
422
- didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
423
- ) -> Bool {
430
+ init(launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) {
431
+ self.launchOptions = launchOptions
424
432
  let delegate = ReactNativeDelegate()
425
- let factory = ExpoReactNativeFactory(delegate: delegate)
426
433
  delegate.dependencyProvider = RCTAppDependencyProvider()
427
-
428
- reactNativeDelegate = delegate
429
- reactNativeFactory = factory
430
-
431
- window = UIWindow(frame: UIScreen.main.bounds)
432
- factory.startReactNative(
433
- withModuleName: "main",
434
- in: window,
435
- launchOptions: launchOptions
436
- )
437
-
438
- return super.application(application, didFinishLaunchingWithOptions: launchOptions)
434
+ self.delegate = delegate
435
+ self.factory = ExpoReactNativeFactory(delegate: delegate)
439
436
  }
440
437
  }
441
438
 
@@ -454,48 +451,76 @@ class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
454
451
  }
455
452
  ```
456
453
 
457
- The module name `"main"` must match what the JS side registers with `AppRegistry.registerComponent("main", () => App)`.
454
+ Keep Swift import access levels consistent with the generated Expo module provider (SDK 55 and 57 providers use `internal import Expo`).
458
455
 
459
- ### Embedding RN inside an existing screen (not the root window)
456
+ Create and retain `ReactNativeRuntime(launchOptions: launchOptions)` from the existing app delegate's launch callback. Forward Expo module lifecycle callbacks as described in [feature integration](./feature-integration.md#forward-lifecycle-events). If your delegate can inherit from `ExpoAppDelegate`, call `super` from its overrides; otherwise use the subscriber manager while preserving the existing superclass and host behavior.
460
457
 
461
- If you do not want React Native to take over the whole window, instantiate the factory the same way but mount the produced root view inside an existing `UIViewController`:
458
+ The code above selects Metro in Debug and the embedded bundle in Release. It does not configure an Updates controller or a development-client launcher. Those integrations need their own SDK-matched delegate setup.
459
+
460
+ ### Present a React Native screen
462
461
 
463
462
  ```swift
464
463
  import UIKit
465
- import React
466
- import Expo
467
464
 
468
- class ReactNativeScreenViewController: UIViewController {
469
- private var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
470
- private var reactNativeFactory: RCTReactNativeFactory?
465
+ final class ReactNativeScreenViewController: UIViewController {
466
+ private let runtime: ReactNativeRuntime
467
+ private let initialProps: [AnyHashable: Any]?
471
468
 
472
- override func viewDidLoad() {
473
- super.viewDidLoad()
469
+ init(runtime: ReactNativeRuntime, initialProps: [AnyHashable: Any]? = nil) {
470
+ self.runtime = runtime
471
+ self.initialProps = initialProps
472
+ super.init(nibName: nil, bundle: nil)
473
+ }
474
474
 
475
- let delegate = ReactNativeDelegate()
476
- let factory = ExpoReactNativeFactory(delegate: delegate)
477
- delegate.dependencyProvider = RCTAppDependencyProvider()
478
- self.reactNativeDelegate = delegate
479
- self.reactNativeFactory = factory
475
+ @available(*, unavailable)
476
+ required init?(coder: NSCoder) {
477
+ fatalError("Use init(runtime:initialProps:)")
478
+ }
480
479
 
481
- let rootView = factory.rootViewFactory.view(
480
+ override func loadView() {
481
+ view = runtime.factory.rootViewFactory.view(
482
482
  withModuleName: "main",
483
- initialProperties: nil,
484
- launchOptions: nil
483
+ initialProperties: initialProps,
484
+ launchOptions: runtime.launchOptions
485
485
  )
486
- rootView.frame = view.bounds
487
- rootView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
488
- view.addSubview(rootView)
489
486
  }
490
487
  }
491
488
  ```
492
489
 
493
- Present it like any other view controller:
490
+ From the existing UIKit controller, using the runtime supplied by the app:
494
491
 
495
492
  ```swift
496
- navigationController?.pushViewController(ReactNativeScreenViewController(), animated: true)
493
+ let screen = ReactNativeScreenViewController(
494
+ runtime: runtime,
495
+ initialProps: ["userId": "123"]
496
+ )
497
+ navigationController?.pushViewController(screen, animated: true)
497
498
  ```
498
499
 
500
+ For SwiftUI, retain the existing `@main struct HostApp: App`. If it has no delegate, attach one with `@UIApplicationDelegateAdaptor(AppDelegate.self)`; if it already has one, extend that delegate. Pass the retained runtime through the host's view hierarchy and wrap the controller:
501
+
502
+ ```swift
503
+ import SwiftUI
504
+
505
+ struct EmbeddedReactScreen: UIViewControllerRepresentable {
506
+ let runtime: ReactNativeRuntime
507
+ let userId: String
508
+
509
+ func makeUIViewController(context: Context) -> ReactNativeScreenViewController {
510
+ ReactNativeScreenViewController(
511
+ runtime: runtime,
512
+ initialProps: ["userId": userId]
513
+ )
514
+ }
515
+
516
+ func updateUIViewController(_ controller: ReactNativeScreenViewController, context: Context) {}
517
+ }
518
+ ```
519
+
520
+ Present `EmbeddedReactScreen` from the host's sheet or navigation destination. Initial props are creation-time input; use messaging/shared state for subsequent changes. For input registration, result handling, and dismissal, read [feature integration](./feature-integration.md).
521
+
522
+ Only use `factory.startReactNative(withModuleName:in:launchOptions:)` with a window when the task explicitly calls for making RN the app's root. It is not necessary for this embedded-screen recipe.
523
+
499
524
  > **Monorepo iOS:** `pod install` is run from `ios/`, but Node module resolution starts from the Expo project root. Pass `EXPO_PROJECT_ROOT=/absolute/path/to/expo-project` to the `pod install` invocation if autolinking cannot find the Expo project automatically.
500
525
 
501
526
  ---
@@ -513,7 +538,7 @@ Build and run the native app normally (Android Studio / Xcode). Navigate to your
513
538
  ### Development vs. production
514
539
 
515
540
  - **Development** — Metro serves the JS bundle with hot reloading over HTTP. Debug builds use the Metro URL via `RCTBundleURLProvider` (iOS) or the dev server detection in `ReactActivity` (Android).
516
- - **Production** — Metro is not used. Run `expo export:embed` (invoked automatically by the React Native Gradle plugin and the iOS build phase) to embed the bundle into the APK/IPA.
541
+ - **Production** — Metro is not used. The configured Gradle/Xcode build phases invoke `export:embed`. Stop Metro and run the host in Release; verify input, result, dismissal, and reopening as in [feature integration](./feature-integration.md#acceptance-scenario).
517
542
 
518
543
  For Metro connection issues, build failures, missing modules, or arch mismatches, see [./troubleshooting.md](./troubleshooting.md).
519
544