vybekiit 0.7.26 → 0.7.28
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.
- package/dist/bin.js +3910 -1300
- package/dist/global-guidance/language.md +443 -0
- package/dist/global-skills/add-ai/SKILL.md +1 -1
- package/dist/global-skills/add-analytics/SKILL.md +1 -1
- package/dist/global-skills/add-blog/SKILL.md +1 -1
- package/dist/global-skills/add-crud/SKILL.md +1 -1
- package/dist/global-skills/add-files/SKILL.md +1 -1
- package/dist/global-skills/add-images/SKILL.md +1 -1
- package/dist/global-skills/add-language/SKILL.md +1 -1
- package/dist/global-skills/add-notifications/SKILL.md +1 -1
- package/dist/global-skills/add-realtime/SKILL.md +1 -1
- package/dist/global-skills/add-route/SKILL.md +1 -1
- package/dist/global-skills/add-search/SKILL.md +1 -1
- package/dist/global-skills/add-signin/SKILL.md +1 -1
- package/dist/global-skills/add-teams/SKILL.md +1 -1
- package/dist/global-skills/add-upload/SKILL.md +1 -1
- package/dist/global-skills/aws-cdk/SKILL.md +19 -5
- package/dist/global-skills/aws-cdk/references/fast-deployments.md +191 -0
- package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +16 -0
- package/dist/global-skills/aws-cloudformation/SKILL.md +16 -26
- package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +7 -3
- package/dist/global-skills/aws-cloudformation/references/cloudformation-language-server.md +177 -0
- package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +8 -2
- package/dist/global-skills/aws-cloudformation/references/persist-template-context.script.md +5 -8
- package/dist/global-skills/aws-cloudformation/references/retrieve-template-context.script.md +1 -1
- package/dist/global-skills/aws-cloudformation/references/security-considerations.md +51 -0
- package/dist/global-skills/aws-cloudformation/references/troubleshoot-failed-stack.script.md +138 -0
- package/dist/global-skills/aws-cloudformation/references/{validate-cloudformation-template.script.md → validate-with-cfn-lint.script.md} +15 -27
- package/dist/global-skills/aws-cloudformation/references/validate-with-cloudformation-validate.script.md +181 -0
- package/dist/global-skills/aws-cloudformation/references/validation-tool-selection.md +44 -0
- package/dist/global-skills/aws-serverless/SKILL.md +9 -1
- package/dist/global-skills/aws-serverless/references/architecture.md +3 -1
- package/dist/global-skills/aws-serverless/references/lambda.md +3 -1
- package/dist/global-skills/aws-serverless/references/orchestration.md +1 -0
- package/dist/global-skills/back-up-my-code/SKILL.md +1 -1
- package/dist/global-skills/better-auth-best-practices/SKILL.md +18 -8
- package/dist/global-skills/buy-domain/SKILL.md +1 -1
- package/dist/global-skills/check-safety/SKILL.md +1 -1
- package/dist/global-skills/configure-capabilities/SKILL.md +1 -1
- package/dist/global-skills/connect-account/SKILL.md +1 -1
- package/dist/global-skills/connect-account-backend/SKILL.md +1 -1
- package/dist/global-skills/design-my-data/SKILL.md +1 -1
- package/dist/global-skills/doctor/SKILL.md +1 -1
- package/dist/global-skills/eas-app-stores/SKILL.md +31 -15
- package/dist/global-skills/eas-app-stores/agents/openai.yaml +2 -2
- package/dist/global-skills/eas-app-stores/references/ios-app-store.md +37 -32
- package/dist/global-skills/eas-app-stores/references/native-ios.md +167 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +3 -7
- package/dist/global-skills/eas-app-stores/references/testflight.md +39 -35
- package/dist/global-skills/eas-simulator/SKILL.md +48 -26
- package/dist/global-skills/eas-simulator/references/controllers.md +32 -3
- package/dist/global-skills/eas-simulator/references/run-your-app.md +34 -4
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -4
- package/dist/global-skills/eas-update/SKILL.md +146 -0
- package/dist/global-skills/eas-update/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-animation/RECIPES.md +2 -2
- package/dist/global-skills/expo-animation/SKILL.md +9 -2
- package/dist/global-skills/expo-brownfield/SKILL.md +18 -11
- package/dist/global-skills/expo-brownfield/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +94 -69
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +40 -42
- package/dist/global-skills/expo-brownfield/references/comparison.md +5 -5
- package/dist/global-skills/expo-brownfield/references/feature-integration.md +163 -0
- package/dist/global-skills/expo-brownfield/references/troubleshooting.md +17 -17
- package/dist/global-skills/expo-brownfield/references/version-compatibility.md +40 -0
- package/dist/global-skills/expo-data-fetching/SKILL.md +27 -6
- package/dist/global-skills/expo-design-system/SKILL.md +27 -7
- package/dist/global-skills/expo-design-system/references/audit.md +7 -2
- package/dist/global-skills/expo-design-system/references/native-slop.md +74 -0
- package/dist/global-skills/expo-examples/SKILL.md +0 -1
- package/dist/global-skills/expo-examples/references/catalog.md +1 -1
- package/dist/global-skills/expo-migrate-module/SKILL.md +21 -10
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +80 -23
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +162 -11
- package/dist/global-skills/expo-native-ui/SKILL.md +25 -16
- package/dist/global-skills/expo-native-ui/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-native-ui/references/controls.md +5 -46
- package/dist/global-skills/expo-native-ui/references/icons.md +21 -2
- package/dist/global-skills/expo-native-ui/references/media.md +15 -20
- package/dist/global-skills/expo-native-ui/references/visual-effects.md +12 -11
- package/dist/global-skills/expo-overview/SKILL.md +17 -12
- package/dist/global-skills/expo-router/SKILL.md +5 -3
- package/dist/global-skills/expo-router/references/tabs.md +5 -5
- package/dist/global-skills/expo-upgrade/SKILL.md +3 -1
- package/dist/global-skills/expo-web-to-native/references/false-friends.md +2 -2
- package/dist/global-skills/expo-web-to-native/references/native-patterns.md +1 -1
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +13 -16
- package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +4 -5
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +4 -4
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +3 -3
- package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +4 -5
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +3 -3
- package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +24 -25
- package/dist/global-skills/firebase-auth-basics/references/security_rules.md +4 -2
- package/dist/global-skills/firebase-crashlytics/references/android_setup.md +7 -4
- package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +2 -3
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -1
- package/dist/global-skills/firebase-data-connect/examples.md +4 -4
- package/dist/global-skills/firebase-data-connect/reference/config.md +5 -4
- package/dist/global-skills/firebase-data-connect/reference/realtime.md +1 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +2 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +2 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +17 -6
- package/dist/global-skills/firebase-data-connect/reference/security.md +5 -5
- package/dist/global-skills/firebase-data-connect/templates.md +2 -1
- package/dist/global-skills/firebase-firestore/SKILL.md +20 -8
- package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +5 -4
- package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +12 -3
- package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +16 -18
- package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +1 -1
- package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +5 -1
- package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +7 -7
- package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +5 -5
- package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +4 -4
- package/dist/global-skills/firebase-firestore/references/standard/indexes.md +16 -18
- package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +1 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +0 -5
- package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +36 -8
- package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +1 -7
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +17 -6
- package/dist/global-skills/{firebase-firestore/references/standard/security_rules.md → firestore-rules-creation/SKILL.md} +24 -13
- package/dist/global-skills/go-live/SKILL.md +1 -1
- package/dist/global-skills/grow-my-customers/SKILL.md +23 -0
- package/dist/global-skills/harden/SKILL.md +1 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +25 -25
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +141 -285
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -15
- package/dist/global-skills/instrument-feature-flags/references/api.md +4 -11
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +1 -13
- package/dist/global-skills/instrument-feature-flags/references/django.md +14 -27
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +20 -79
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +1 -9
- package/dist/global-skills/instrument-feature-flags/references/flask.md +13 -13
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +3 -24
- package/dist/global-skills/instrument-feature-flags/references/go.md +3 -15
- package/dist/global-skills/instrument-feature-flags/references/ios.md +4 -17
- package/dist/global-skills/instrument-feature-flags/references/java.md +5 -13
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +13 -17
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +25 -32
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +8 -15
- package/dist/global-skills/instrument-feature-flags/references/php.md +1 -15
- package/dist/global-skills/instrument-feature-flags/references/python.md +2 -15
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +13 -15
- package/dist/global-skills/instrument-feature-flags/references/react.md +17 -21
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +37 -83
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +2 -15
- package/dist/global-skills/instrument-feature-flags/references/rust.md +13 -25
- package/dist/global-skills/instrument-feature-flags/references/usage.md +14 -63
- package/dist/global-skills/instrument-feature-flags/references/web.md +9 -14
- package/dist/global-skills/instrument-product-analytics/SKILL.md +29 -29
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/android.md +72 -107
- package/dist/global-skills/instrument-product-analytics/references/angular.md +26 -28
- package/dist/global-skills/instrument-product-analytics/references/astro.md +13 -24
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +45 -63
- package/dist/global-skills/instrument-product-analytics/references/django.md +14 -27
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +20 -79
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +47 -49
- package/dist/global-skills/instrument-product-analytics/references/flask.md +13 -13
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +60 -90
- package/dist/global-skills/instrument-product-analytics/references/go.md +17 -56
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +15 -15
- package/dist/global-skills/instrument-product-analytics/references/ios.md +11 -15
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +13 -17
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +25 -32
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +13 -27
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +14 -28
- package/dist/global-skills/instrument-product-analytics/references/php.md +33 -84
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +229 -9
- package/dist/global-skills/instrument-product-analytics/references/python.md +415 -106
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +161 -155
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +12 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +15 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +12 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +26 -41
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +37 -83
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +48 -108
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +18 -24
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +17 -19
- package/dist/global-skills/instrument-product-analytics/references/usage.md +14 -63
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +29 -28
- package/dist/global-skills/manifest.json +8 -2
- package/dist/global-skills/mongodb-search-and-ai/SKILL.md +28 -37
- package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +438 -0
- package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +60 -4
- package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +46 -108
- package/dist/global-skills/neon/SKILL.md +207 -213
- package/dist/global-skills/neon/references/auth.md +12 -0
- package/dist/global-skills/neon/references/claimable-neon.md +10 -14
- package/dist/global-skills/neon/references/function-triggers.md +53 -0
- package/dist/global-skills/neon/references/logs-loki.md +61 -0
- package/dist/global-skills/neon/references/parse-env.md +32 -0
- package/dist/global-skills/neon/references/sdk.md +7 -0
- package/dist/global-skills/neon-ai-gateway/SKILL.md +14 -16
- package/dist/global-skills/neon-auth/SKILL.md +155 -0
- package/dist/global-skills/neon-auth/references/managed-auth.md +173 -0
- package/dist/global-skills/neon-auth/references/self-managed.md +25 -0
- package/dist/global-skills/neon-functions/SKILL.md +159 -84
- package/dist/global-skills/neon-functions/references/ai-sdk.md +4 -6
- package/dist/global-skills/neon-functions/references/function-triggers.md +249 -0
- package/dist/global-skills/neon-functions/references/mastra-studio.md +3 -3
- package/dist/global-skills/neon-functions/references/mcp.md +1 -1
- package/dist/global-skills/neon-functions/references/production-hardening.md +340 -0
- package/dist/global-skills/neon-functions/references/sse.md +8 -5
- package/dist/global-skills/neon-object-storage/SKILL.md +10 -11
- package/dist/global-skills/neon-postgres/SKILL.md +120 -17
- package/dist/global-skills/neon-postgres/references/full-text-search.md +99 -0
- package/dist/global-skills/neon-postgres/references/hybrid-search.md +90 -0
- package/dist/global-skills/neon-postgres/references/lakebase-search-drizzle.md +172 -0
- package/dist/global-skills/neon-postgres/references/vector-search.md +137 -0
- package/dist/global-skills/neon-postgres-branches/SKILL.md +3 -3
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -1
- package/dist/global-skills/onboarding/SKILL.md +16 -14
- package/dist/global-skills/plan-my-idea/SKILL.md +1 -1
- package/dist/global-skills/publish-app/SKILL.md +1 -1
- package/dist/global-skills/publish-extension/SKILL.md +1 -1
- package/dist/global-skills/resend/SKILL.md +4 -2
- package/dist/global-skills/resend/references/broadcasts.md +6 -1
- package/dist/global-skills/resend/references/receiving.md +29 -10
- package/dist/global-skills/resend/references/sending/email-management.md +14 -4
- package/dist/global-skills/resend/references/topics.md +9 -6
- package/dist/global-skills/resend/references/usage.md +117 -0
- package/dist/global-skills/resend/references/webhooks.md +59 -2
- package/dist/global-skills/reset-password/SKILL.md +1 -1
- package/dist/global-skills/save-data/SKILL.md +1 -1
- package/dist/global-skills/setup-email/SKILL.md +1 -1
- package/dist/global-skills/setup-payments/SKILL.md +1 -1
- package/dist/global-skills/setup-sms/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-email-link/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-google/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-phone/SKILL.md +1 -1
- package/dist/global-skills/stripe-best-practices/SKILL.md +35 -29
- package/dist/global-skills/stripe-best-practices/references/billing.md +9 -2
- package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +3 -1
- package/dist/global-skills/stripe-best-practices/references/tax.md +39 -20
- package/dist/global-skills/supabase/SKILL.md +6 -0
- package/dist/global-skills/track-errors/SKILL.md +1 -1
- package/dist/global-skills/update-kit/SKILL.md +1 -1
- package/dist/global-skills/use-railway/SKILL.md +42 -22
- package/dist/global-skills/use-railway/references/analyze-db.md +7 -6
- package/dist/global-skills/use-railway/references/cloud-agents.md +70 -0
- package/dist/global-skills/use-railway/references/configure.md +17 -2
- package/dist/global-skills/use-railway/references/databases.md +107 -0
- package/dist/global-skills/use-railway/references/deploy.md +5 -5
- package/dist/global-skills/use-railway/references/feature-flags.md +25 -13
- package/dist/global-skills/use-railway/references/iac.md +66 -77
- package/dist/global-skills/use-railway/references/operate.md +26 -3
- package/dist/global-skills/use-railway/references/request.md +31 -23
- package/dist/global-skills/use-railway/references/setup.md +16 -5
- package/dist/global-skills/use-railway/references/tracing.md +261 -0
- package/dist/global-skills/use-railway/references/usage.md +52 -0
- package/dist/global-skills/validate-my-idea/SKILL.md +54 -0
- package/dist/global-skills/{feedback → vybekiit-feedback}/SKILL.md +17 -13
- package/dist/global-skills/watch-my-app/SKILL.md +53 -0
- package/dist/global-skills/wire-auth/SKILL.md +1 -1
- package/dist/global-skills/wire-database/SKILL.md +1 -1
- package/dist/global-skills/wire-email/SKILL.md +1 -1
- package/dist/global-skills/wire-payments/SKILL.md +1 -1
- package/dist/global-skills/workers-best-practices/SKILL.md +36 -103
- package/dist/global-skills/workers-best-practices/references/configuration.md +139 -0
- package/dist/global-skills/workers-best-practices/references/platform-apis.md +51 -0
- package/dist/global-skills/workers-best-practices/references/{rules.md → runtime-patterns.md} +13 -137
- package/dist/global-skills/wrangler/SKILL.md +48 -901
- package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +19 -15
- package/package.json +9 -8
- package/dist/global-skills/expo-native-ui/references/animations.md +0 -220
- package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +0 -577
- 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:
|
|
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
|
|
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
|
-
-
|
|
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
|
|
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
|
-
-
|
|
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
|
|
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
|
-
##
|
|
53
|
+
## Select compatible versions
|
|
47
54
|
|
|
48
|
-
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
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: "
|
|
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
|
|
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
|
|
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
|
-
-
|
|
19
|
-
- **CocoaPods** (iOS) —
|
|
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
|
|
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
|
|
28
|
+
npx create-expo-app@latest my-project --template blank@latest
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
|
|
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)
|
|
33
|
+
## 2) Establish the project layout
|
|
34
34
|
|
|
35
|
-
|
|
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
|
-
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
414
|
+
### Own the runtime without replacing the native window
|
|
405
415
|
|
|
406
|
-
|
|
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
|
-
@
|
|
414
|
-
class
|
|
415
|
-
|
|
424
|
+
@MainActor
|
|
425
|
+
final class ReactNativeRuntime {
|
|
426
|
+
private let delegate: ReactNativeDelegate
|
|
427
|
+
let factory: ExpoReactNativeFactory
|
|
428
|
+
let launchOptions: [UIApplication.LaunchOptionsKey: Any]?
|
|
416
429
|
|
|
417
|
-
|
|
418
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
470
|
-
private
|
|
465
|
+
final class ReactNativeScreenViewController: UIViewController {
|
|
466
|
+
private let runtime: ReactNativeRuntime
|
|
467
|
+
private let initialProps: [AnyHashable: Any]?
|
|
471
468
|
|
|
472
|
-
|
|
473
|
-
|
|
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
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
self.reactNativeFactory = factory
|
|
475
|
+
@available(*, unavailable)
|
|
476
|
+
required init?(coder: NSCoder) {
|
|
477
|
+
fatalError("Use init(runtime:initialProps:)")
|
|
478
|
+
}
|
|
480
479
|
|
|
481
|
-
|
|
480
|
+
override func loadView() {
|
|
481
|
+
view = runtime.factory.rootViewFactory.view(
|
|
482
482
|
withModuleName: "main",
|
|
483
|
-
initialProperties:
|
|
484
|
-
launchOptions:
|
|
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
|
-
|
|
490
|
+
From the existing UIKit controller, using the runtime supplied by the app:
|
|
494
491
|
|
|
495
492
|
```swift
|
|
496
|
-
|
|
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.
|
|
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
|
|