packwise-skills 1.0.0 → 1.2.0

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 (53) hide show
  1. package/.cursorrules +23 -23
  2. package/CLAUDE.md +25 -25
  3. package/LICENSE +21 -0
  4. package/README.md +404 -295
  5. package/audit.md +224 -224
  6. package/bin/packwise.js +322 -155
  7. package/install.sh +123 -0
  8. package/package.json +32 -31
  9. package/skill.md +944 -719
  10. package/sub-skills/ai/local-llm.md +183 -183
  11. package/sub-skills/ai/python-ml.md +164 -164
  12. package/sub-skills/backend/go-server.md +184 -184
  13. package/sub-skills/backend/java-spring.md +241 -241
  14. package/sub-skills/backend/node-server.md +164 -164
  15. package/sub-skills/backend/php-laravel.md +175 -175
  16. package/sub-skills/backend/python-server.md +164 -164
  17. package/sub-skills/backend/rust-backend.md +118 -118
  18. package/sub-skills/cli/python-cli.md +236 -236
  19. package/sub-skills/cli/sdk-library.md +497 -497
  20. package/sub-skills/cloud/ci-cd-pipelines.md +350 -350
  21. package/sub-skills/cloud/docker.md +191 -191
  22. package/sub-skills/cloud/kubernetes.md +277 -277
  23. package/sub-skills/cloud/payment-integration.md +307 -307
  24. package/sub-skills/cross-platform/multiplatform.md +252 -252
  25. package/sub-skills/desktop/electron.md +783 -783
  26. package/sub-skills/desktop/game-dev.md +443 -443
  27. package/sub-skills/desktop/native-app.md +123 -123
  28. package/sub-skills/desktop/scenarios.md +443 -443
  29. package/sub-skills/desktop/smart-platforms.md +324 -324
  30. package/sub-skills/desktop/tauri.md +428 -428
  31. package/sub-skills/desktop/vr-ar.md +252 -252
  32. package/sub-skills/desktop/web-to-desktop.md +153 -153
  33. package/sub-skills/embedded/car-infotainment.md +129 -129
  34. package/sub-skills/embedded/esp32.md +184 -184
  35. package/sub-skills/embedded/ros.md +150 -150
  36. package/sub-skills/embedded/stm32.md +160 -160
  37. package/sub-skills/mobile/android.md +322 -322
  38. package/sub-skills/mobile/capacitor.md +232 -232
  39. package/sub-skills/mobile/flutter-mobile.md +138 -138
  40. package/sub-skills/mobile/harmonyos.md +150 -150
  41. package/sub-skills/mobile/ios.md +245 -245
  42. package/sub-skills/mobile/react-native.md +443 -443
  43. package/sub-skills/mobile/wearables.md +230 -230
  44. package/sub-skills/plugins/browser-extension.md +308 -308
  45. package/sub-skills/plugins/jetbrains-plugin.md +226 -226
  46. package/sub-skills/plugins/vscode-extension.md +204 -204
  47. package/sub-skills/security/security-tools.md +174 -174
  48. package/sub-skills/web/monorepo.md +274 -274
  49. package/sub-skills/web/pwa.md +220 -220
  50. package/sub-skills/web/serverless-edge.md +295 -295
  51. package/sub-skills/web/spa.md +266 -266
  52. package/sub-skills/web/ssr.md +228 -228
  53. package/sub-skills/web/wasm.md +243 -243
@@ -1,443 +1,443 @@
1
- # React Native Build Sub-Skill
2
-
3
- Build mobile apps using React Native with JavaScript or TypeScript.
4
-
5
- **Current version**: React Native 0.86.x / Expo SDK 56 (2025-2026)
6
-
7
- > ⚠️ **Critical breaking changes since RN 0.76**:
8
- > - **Legacy architecture fully removed (v0.84)**: Old bridge modules, `NativeModules` direct access, `requireNativeComponent` all fail. ALL native modules must have TurboModule spec files.
9
- > - **JSC engine removed (v0.81)**: Hermes is the sole JS engine. `hermesEnabled` property no longer meaningful.
10
- > - **iOS minimum deployment target**: 13.4 (v0.76) → **16.0** (v0.78+). Apps targeting older iOS will be rejected.
11
- > - **Deep imports removed (v0.82)**: `require('react-native/Libraries/...')` without `.default` breaks.
12
- > - **Node.js 22.11+ required (v0.84)**.
13
- > - **Expo SDK 56** required for RN 0.85/0.86 (was SDK 52 for RN 0.76).
14
- > - **Metro package exports** enabled by default (v0.79) — may break Firebase, AWS Amplify.
15
- > - **React 19**: `propTypes` removed, `ref` is regular prop, string refs removed.
16
- > - **Jest preset moved (v0.85)**: `preset: 'react-native'` → `preset: '@react-native/jest-preset'`.
17
- > - See [reactnative.dev/blog](https://reactnative.dev/blog) for version-specific guides.
18
-
19
- ## When to Use
20
-
21
- - Team has React/JavaScript/TypeScript experience
22
- - Need cross-platform app (iOS + Android) with near-native performance
23
- - Want to leverage the React ecosystem and component model
24
-
25
- ## Key Features
26
-
27
- - **Hermes engine** — default JS engine since RN 0.70, optimized for mobile (faster startup, lower memory)
28
- - **Fabric renderer** — new architecture with synchronous native calls
29
- - **TurboModules** — lazy-loaded native modules with type-safe JSI bindings
30
- - **Expo ecosystem** — managed workflow for rapid development without Xcode/Android Studio setup
31
-
32
- ## Prerequisites
33
-
34
- ```bash
35
- # React Native CLI (bare workflow)
36
- npm install -g react-native-cli
37
-
38
- # Android
39
- # Android Studio, JDK 17, Android SDK 34+
40
-
41
- # iOS (macOS only)
42
- # Xcode 15+, CocoaPods (sudo gem install cocoapods)
43
- ```
44
-
45
- ## Two Workflows: Expo vs Bare
46
-
47
- | Feature | Expo (Managed) | Bare Workflow |
48
- |---------|---------------|---------------|
49
- | Setup | `npx create-expo-app` | `npx react-native init` |
50
- | Native code | No direct access | Full control |
51
- | Build service | EAS Cloud Build | Local + CI |
52
- | OTA updates | Yes (EAS Update) | Manual |
53
- | Best for | New projects, rapid prototyping | Existing native modules, full control |
54
-
55
- ## Expo Managed Workflow (Recommended for New Projects)
56
-
57
- ```bash
58
- # Create project
59
- npx create-expo-app@latest MyApp --template blank-typescript
60
- cd MyApp
61
-
62
- # Local development
63
- npx expo start # Start dev server
64
- npx expo start --ios # Run on iOS simulator
65
- npx expo start --android # Run on Android emulator
66
-
67
- # Export for production
68
- npx expo export --platform all
69
- ```
70
-
71
- ### EAS Build (Cloud Build Service)
72
-
73
- ```bash
74
- # Install EAS CLI
75
- npm install -g eas-cli
76
- eas login
77
-
78
- # Configure build profiles
79
- # Creates eas.json with development/preview/production profiles
80
- eas build:configure
81
-
82
- # Build for Android (AAB for Play Store) — requires Node 22.11+ for RN 0.84+
83
- eas build --platform android --profile production
84
-
85
- # Build for iOS (IPA for App Store) — minimum iOS 16.0 for RN 0.78+
86
- eas build --platform ios --profile production
87
-
88
- # Build for both platforms simultaneously
89
- eas build --platform all --profile production
90
-
91
- # Local build (no cloud credits needed)
92
- eas build --platform android --profile production --local
93
- ```
94
-
95
- ```json
96
- // eas.json
97
- {
98
- "cli": { "version": ">= 12.0.0" },
99
- "build": {
100
- "development": {
101
- "developmentClient": true,
102
- "distribution": "internal"
103
- },
104
- "preview": {
105
- "distribution": "internal",
106
- "android": { "buildType": "apk" }
107
- },
108
- "production": {
109
- "android": {
110
- "buildType": "app-bundle"
111
- },
112
- "ios": {
113
- "autoIncrement": true
114
- }
115
- }
116
- },
117
- "submit": {
118
- "production": {
119
- "ios": {
120
- "appleId": "your-apple-id@example.com",
121
- "ascAppId": "your-app-store-connect-app-id"
122
- },
123
- "android": {
124
- "serviceAccountKeyPath": "./google-services.json",
125
- "track": "production"
126
- }
127
- }
128
- }
129
- }
130
- ```
131
-
132
- ### EAS Update (OTA Updates)
133
-
134
- ```bash
135
- # Push OTA update (no app store review needed)
136
- eas update --branch production --message "Fix login bug"
137
-
138
- # Rollback to previous version
139
- eas update --branch production --message "Rollback" --republish
140
- ```
141
-
142
- ## Bare Workflow (Full Native Control)
143
-
144
- ```bash
145
- # Create project
146
- npx @react-native-community/cli init MyApp --version 0.76
147
- cd MyApp
148
-
149
- # Verify setup
150
- npx react-native doctor
151
-
152
- # Run
153
- npx react-native run-android
154
- npx react-native run-ios
155
- ```
156
-
157
- ### Hermes Engine (Default)
158
-
159
- Hermes is the default JS engine since RN 0.70. Verify it's enabled:
160
-
161
- ```javascript
162
- // android/gradle.properties
163
- hermesEnabled=true // should be true by default
164
-
165
- // ios/Podfile (auto-configured)
166
- :hermes_enabled => true
167
- ```
168
-
169
- ```bash
170
- # Verify Hermes is active at runtime
171
- console.log('Hermes:', global.HermesInternal != null); // should print true
172
- ```
173
-
174
- ### Android Release Build
175
-
176
- ```bash
177
- # Generate signing keystore
178
- keytool -genkeypair -v -storetype PKCS12 \
179
- -keystore android/app/my-release-key.keystore \
180
- -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
181
-
182
- # Set signing config in android/app/build.gradle.kts
183
- # OR use environment variables (recommended for CI):
184
- export MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
185
- export MYAPP_RELEASE_KEY_ALIAS=my-key-alias
186
- export MYAPP_RELEASE_STORE_PASSWORD=your-password
187
- export MYAPP_RELEASE_KEY_PASSWORD=your-password
188
-
189
- # Build AAB (Play Store)
190
- cd android && ./gradlew bundleRelease
191
- # Output: android/app/build/outputs/bundle/release/app-release.aab
192
-
193
- # Build APK (direct distribution)
194
- cd android && ./gradlew assembleRelease
195
- # Output: android/app/build/outputs/apk/release/app-release.apk
196
-
197
- # Run release build on device
198
- npx react-native run-android --mode=release
199
- ```
200
-
201
- ### iOS Release Build
202
-
203
- ```bash
204
- # Install pods
205
- cd ios && pod install && cd ..
206
-
207
- # Build via Xcode
208
- open ios/MyApp.xcworkspace
209
- # Product → Archive → Distribute App
210
-
211
- # Build via command line (requires fastlane)
212
- sudo gem install fastlane
213
- cd ios && fastlane release
214
-
215
- # TestFlight upload
216
- cd ios && fastlane beta
217
- ```
218
-
219
- ## React Native vs Flutter
220
-
221
- | Feature | React Native | Flutter |
222
- |---------|-------------|---------|
223
- | Language | JavaScript/TypeScript | Dart |
224
- | UI | Native components | Custom rendering (Skia/Impeller) |
225
- | Hot reload | Fast Refresh | Hot reload |
226
- | Performance | Near-native (Hermes + Fabric) | Near-native (AOT compilation) |
227
- | Ecosystem | Huge (npm) | Growing (pub.dev) |
228
- | Web support | Via react-native-web | First-class |
229
- | Learning curve | Low (if you know React) | Medium (Dart is less common) |
230
-
231
- ## Common Pitfalls
232
-
233
- | Issue | Fix |
234
- |-------|-----|
235
- | Metro bundler cache issues | `npx react-native start --reset-cache` |
236
- | iOS build fails after pod install | `cd ios && pod deinstall && pod install`; check Ruby version (3.1+) |
237
- | Android SDK not found | Set `ANDROID_HOME` env variable; verify with `npx react-native doctor` |
238
- | Hermes not enabled | Check `hermesEnabled=true` in `android/gradle.properties`; run `pod install` |
239
- | Release build crashes but debug works | Check ProGuard rules; add keep rules for native modules |
240
- | App size too large | Enable Hermes; use ProGuard; split APKs by ABI |
241
- | Network request fails in release | iOS: add App Transport Security exception in Info.plist |
242
- | `react-native-reanimated` crash | Ensure Babel plugin is in `babel.config.js` |
243
- | EAS build timeout | Use `--local` flag for local builds; check build logs for specific errors |
244
- | New Architecture compatibility | Check library support at reactnative.directory; many libs still on old arch |
245
- | "Namespace not specified" error | AGP 8.x requires `namespace` in `android/app/build.gradle`; remove `package=` from AndroidManifest.xml |
246
- | Legacy arch modules crash (0.84+) | Old bridge modules fully removed; must use TurboModule spec files |
247
- | JSC not available (0.81+) | Hermes is sole engine; `hermesEnabled` toggle no longer meaningful |
248
- | iOS build rejected (0.78+) | Minimum iOS deployment target is now 16.0 (was 13.4) |
249
- | Deep import fails (0.82+) | `require('react-native/Libraries/...')` removed; use top-level exports |
250
- | Metro package exports break (0.79+) | Add `resolver.unstable_enablePackageExports: false` to metro.config.js to opt out |
251
- | Jest preset not found (0.85+) | Change `preset: 'react-native'` to `preset: '@react-native/jest-preset'` |
252
- | Firebase/Amplify build fails (0.79+) | Metro exports resolution enabled by default; see Metro config fix above |
253
- | App Store rejected: missing Privacy Manifest | Add `PrivacyInfo.xcprivacy` to iOS project (see below) |
254
- | `ClassNotFoundException` on release | Missing ProGuard rules — see ProGuard section below |
255
-
256
- ## Critical: AGP 8.x Namespace Requirement
257
-
258
- AGP 8.0+ removed `package` attribute from `AndroidManifest.xml`. You MUST use `namespace` in `build.gradle`:
259
-
260
- ```gradle
261
- // android/app/build.gradle
262
- android {
263
- namespace "com.yourapp" // REQUIRED in AGP 8.x
264
- compileSdk 35
265
- defaultConfig {
266
- applicationId "com.yourapp"
267
- minSdkVersion 24
268
- targetSdkVersion 35
269
- }
270
- }
271
- ```
272
-
273
- ```xml
274
- <!-- AndroidManifest.xml — REMOVE package attribute -->
275
- <manifest xmlns:android="http://schemas.android.com/apk/res/android">
276
- <!-- no package="..." attribute -->
277
- </manifest>
278
- ```
279
-
280
- ## New Architecture (Mandatory since RN 0.84)
281
-
282
- Fabric renderer and TurboModules are **mandatory** since React Native 0.84. Legacy architecture code has been completely removed. There is no opt-out.
283
-
284
- ```properties
285
- # android/gradle.properties (RN 0.84+)
286
- # newArchEnabled is no longer configurable — it's always on
287
- hermesEnabled=true # Hermes is the sole engine (JSC removed in 0.81)
288
- ```
289
-
290
- **What this means:**
291
- - ALL native modules must have TurboModule spec files
292
- - Libraries using old `UIManager` bridge calls will NOT work
293
- - `NativeModules` direct access deprecated — use TurboModule specs
294
- - `requireNativeComponent` replaced by Fabric component specs
295
- - Check library compatibility: [reactnative.directory](https://reactnative.directory)
296
-
297
- ## ProGuard Rules (Required for Release Builds)
298
-
299
- > ⚠️ **R8 full mode is now default** for release builds (more aggressive shrinking). Without these rules, your release build WILL crash at runtime. Legacy architecture classes removed in RN 0.84+ may require updated rules.
300
-
301
- ```proguard
302
- # android/app/proguard-rules.pro
303
-
304
- # React Native Core
305
- -keep class com.facebook.react.** { *; }
306
- -keep class com.facebook.hermes.** { *; }
307
- -keep class com.facebook.jni.** { *; }
308
-
309
- # Hermes
310
- -keep class com.facebook.hermes.unicode.** { *; }
311
-
312
- # Native Modules (CRITICAL — R8 strips these without keep rules)
313
- -keepnames class * extends com.facebook.react.bridge.NativeModule
314
- -keepnames class * extends com.facebook.react.TurboModule
315
- -keepclassmembers class * extends com.facebook.react.bridge.NativeModule {
316
- @com.facebook.react.bridge.ReactMethod <methods>;
317
- }
318
-
319
- # Views
320
- -keep class com.facebook.react.views.** { *; }
321
- -keep class com.facebook.react.uimanager.** { *; }
322
- -keep class com.facebook.react.animated.** { *; }
323
-
324
- # Common third-party libraries
325
- -keep class com.swmansion.gesturehandler.** { *; }
326
- -keep class com.swmansion.reanimated.** { *; }
327
- -keep class com.swmansion.rnscreens.** { *; }
328
- -keep class com.reactnativecommunity.asyncstorage.** { *; }
329
- -keep class com.horcrux.svg.** { *; }
330
-
331
- # Expo modules (if using Expo)
332
- -keep class expo.modules.** { *; }
333
-
334
- # OkHttp
335
- -dontwarn okhttp3.**
336
- -keep class okhttp3.** { *; }
337
- ```
338
-
339
- Enable in `android/app/build.gradle`:
340
-
341
- ```gradle
342
- android {
343
- buildTypes {
344
- release {
345
- minifyEnabled true
346
- shrinkResources true
347
- proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
348
- }
349
- }
350
- }
351
- ```
352
-
353
- ## iOS Privacy Manifest (Required for App Store)
354
-
355
- Apple requires `PrivacyInfo.xcprivacy` since Spring 2024. Without it, your app will be rejected.
356
-
357
- ```xml
358
- <!-- ios/YourApp/PrivacyInfo.xcprivacy -->
359
- <?xml version="1.0" encoding="UTF-8"?>
360
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
361
- "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
362
- <plist version="1.0">
363
- <dict>
364
- <key>NSPrivacyTracking</key>
365
- <false/>
366
- <key>NSPrivacyTrackingDomains</key>
367
- <array/>
368
- <key>NSPrivacyCollectedDataTypes</key>
369
- <array/>
370
- <key>NSPrivacyAccessedAPITypes</key>
371
- <array>
372
- <dict>
373
- <key>NSPrivacyAccessedAPIType</key>
374
- <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
375
- <key>NSPrivacyAccessedAPITypeReasons</key>
376
- <array><string>CA92.1</string></array>
377
- </dict>
378
- <dict>
379
- <key>NSPrivacyAccessedAPIType</key>
380
- <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
381
- <key>NSPrivacyAccessedAPITypeReasons</key>
382
- <array><string>C617.1</string></array>
383
- </dict>
384
- <dict>
385
- <key>NSPrivacyAccessedAPIType</key>
386
- <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
387
- <key>NSPrivacyAccessedAPITypeReasons</key>
388
- <array><string>35F9.1</string></array>
389
- </dict>
390
- </array>
391
- </dict>
392
- </plist>
393
- ```
394
-
395
- Add to Xcode: Drag into app group → ensure "Copy Bundle Resources" includes it.
396
-
397
- ## Secure Signing Configuration
398
-
399
- Never commit passwords to version control.
400
-
401
- ```gradle
402
- // android/app/build.gradle — secure signing
403
- signingConfigs {
404
- release {
405
- storeFile file(MYAPP_RELEASE_STORE_FILE ?: System.getenv("MYAPP_RELEASE_STORE_FILE") ?: "release.keystore")
406
- storePassword MYAPP_RELEASE_STORE_PASSWORD ?: System.getenv("MYAPP_RELEASE_STORE_PASSWORD")
407
- keyAlias MYAPP_RELEASE_KEY_ALIAS ?: System.getenv("MYAPP_RELEASE_KEY_ALIAS")
408
- keyPassword MYAPP_RELEASE_KEY_PASSWORD ?: System.getenv("MYAPP_RELEASE_KEY_PASSWORD")
409
- }
410
- }
411
- ```
412
-
413
- ```yaml
414
- # GitHub Actions — decode keystore from secrets
415
- - name: Decode Keystore
416
- run: echo "${{ secrets.RELEASE_KEYSTORE_BASE64 }}" | base64 --decode > android/app/release.keystore
417
- - name: Build Release
418
- env:
419
- MYAPP_RELEASE_STORE_FILE: release.keystore
420
- MYAPP_RELEASE_STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
421
- MYAPP_RELEASE_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
422
- MYAPP_RELEASE_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
423
- run: cd android && ./gradlew bundleRelease
424
- ```
425
-
426
- ## Metro Production Configuration
427
-
428
- ```javascript
429
- // metro.config.js
430
- const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
431
-
432
- const config = {
433
- transformer: {
434
- minifierConfig: {
435
- compress: {
436
- drop_console: true, // Remove console.log in production
437
- },
438
- },
439
- },
440
- };
441
-
442
- module.exports = mergeConfig(getDefaultConfig(__dirname), config);
443
- ```
1
+ # React Native Build Sub-Skill
2
+
3
+ Build mobile apps using React Native with JavaScript or TypeScript.
4
+
5
+ **Current version**: React Native 0.86.x / Expo SDK 56 (2025-2026)
6
+
7
+ > ⚠️ **Critical breaking changes since RN 0.76**:
8
+ > - **Legacy architecture fully removed (v0.84)**: Old bridge modules, `NativeModules` direct access, `requireNativeComponent` all fail. ALL native modules must have TurboModule spec files.
9
+ > - **JSC engine removed (v0.81)**: Hermes is the sole JS engine. `hermesEnabled` property no longer meaningful.
10
+ > - **iOS minimum deployment target**: 13.4 (v0.76) → **16.0** (v0.78+). Apps targeting older iOS will be rejected.
11
+ > - **Deep imports removed (v0.82)**: `require('react-native/Libraries/...')` without `.default` breaks.
12
+ > - **Node.js 22.11+ required (v0.84)**.
13
+ > - **Expo SDK 56** required for RN 0.85/0.86 (was SDK 52 for RN 0.76).
14
+ > - **Metro package exports** enabled by default (v0.79) — may break Firebase, AWS Amplify.
15
+ > - **React 19**: `propTypes` removed, `ref` is regular prop, string refs removed.
16
+ > - **Jest preset moved (v0.85)**: `preset: 'react-native'` → `preset: '@react-native/jest-preset'`.
17
+ > - See [reactnative.dev/blog](https://reactnative.dev/blog) for version-specific guides.
18
+
19
+ ## When to Use
20
+
21
+ - Team has React/JavaScript/TypeScript experience
22
+ - Need cross-platform app (iOS + Android) with near-native performance
23
+ - Want to leverage the React ecosystem and component model
24
+
25
+ ## Key Features
26
+
27
+ - **Hermes engine** — default JS engine since RN 0.70, optimized for mobile (faster startup, lower memory)
28
+ - **Fabric renderer** — new architecture with synchronous native calls
29
+ - **TurboModules** — lazy-loaded native modules with type-safe JSI bindings
30
+ - **Expo ecosystem** — managed workflow for rapid development without Xcode/Android Studio setup
31
+
32
+ ## Prerequisites
33
+
34
+ ```bash
35
+ # React Native CLI (bare workflow)
36
+ npm install -g react-native-cli
37
+
38
+ # Android
39
+ # Android Studio, JDK 17, Android SDK 34+
40
+
41
+ # iOS (macOS only)
42
+ # Xcode 15+, CocoaPods (sudo gem install cocoapods)
43
+ ```
44
+
45
+ ## Two Workflows: Expo vs Bare
46
+
47
+ | Feature | Expo (Managed) | Bare Workflow |
48
+ |---------|---------------|---------------|
49
+ | Setup | `npx create-expo-app` | `npx react-native init` |
50
+ | Native code | No direct access | Full control |
51
+ | Build service | EAS Cloud Build | Local + CI |
52
+ | OTA updates | Yes (EAS Update) | Manual |
53
+ | Best for | New projects, rapid prototyping | Existing native modules, full control |
54
+
55
+ ## Expo Managed Workflow (Recommended for New Projects)
56
+
57
+ ```bash
58
+ # Create project
59
+ npx create-expo-app@latest MyApp --template blank-typescript
60
+ cd MyApp
61
+
62
+ # Local development
63
+ npx expo start # Start dev server
64
+ npx expo start --ios # Run on iOS simulator
65
+ npx expo start --android # Run on Android emulator
66
+
67
+ # Export for production
68
+ npx expo export --platform all
69
+ ```
70
+
71
+ ### EAS Build (Cloud Build Service)
72
+
73
+ ```bash
74
+ # Install EAS CLI
75
+ npm install -g eas-cli
76
+ eas login
77
+
78
+ # Configure build profiles
79
+ # Creates eas.json with development/preview/production profiles
80
+ eas build:configure
81
+
82
+ # Build for Android (AAB for Play Store) — requires Node 22.11+ for RN 0.84+
83
+ eas build --platform android --profile production
84
+
85
+ # Build for iOS (IPA for App Store) — minimum iOS 16.0 for RN 0.78+
86
+ eas build --platform ios --profile production
87
+
88
+ # Build for both platforms simultaneously
89
+ eas build --platform all --profile production
90
+
91
+ # Local build (no cloud credits needed)
92
+ eas build --platform android --profile production --local
93
+ ```
94
+
95
+ ```json
96
+ // eas.json
97
+ {
98
+ "cli": { "version": ">= 12.0.0" },
99
+ "build": {
100
+ "development": {
101
+ "developmentClient": true,
102
+ "distribution": "internal"
103
+ },
104
+ "preview": {
105
+ "distribution": "internal",
106
+ "android": { "buildType": "apk" }
107
+ },
108
+ "production": {
109
+ "android": {
110
+ "buildType": "app-bundle"
111
+ },
112
+ "ios": {
113
+ "autoIncrement": true
114
+ }
115
+ }
116
+ },
117
+ "submit": {
118
+ "production": {
119
+ "ios": {
120
+ "appleId": "your-apple-id@example.com",
121
+ "ascAppId": "your-app-store-connect-app-id"
122
+ },
123
+ "android": {
124
+ "serviceAccountKeyPath": "./google-services.json",
125
+ "track": "production"
126
+ }
127
+ }
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### EAS Update (OTA Updates)
133
+
134
+ ```bash
135
+ # Push OTA update (no app store review needed)
136
+ eas update --branch production --message "Fix login bug"
137
+
138
+ # Rollback to previous version
139
+ eas update --branch production --message "Rollback" --republish
140
+ ```
141
+
142
+ ## Bare Workflow (Full Native Control)
143
+
144
+ ```bash
145
+ # Create project
146
+ npx @react-native-community/cli init MyApp --version 0.76
147
+ cd MyApp
148
+
149
+ # Verify setup
150
+ npx react-native doctor
151
+
152
+ # Run
153
+ npx react-native run-android
154
+ npx react-native run-ios
155
+ ```
156
+
157
+ ### Hermes Engine (Default)
158
+
159
+ Hermes is the default JS engine since RN 0.70. Verify it's enabled:
160
+
161
+ ```javascript
162
+ // android/gradle.properties
163
+ hermesEnabled=true // should be true by default
164
+
165
+ // ios/Podfile (auto-configured)
166
+ :hermes_enabled => true
167
+ ```
168
+
169
+ ```bash
170
+ # Verify Hermes is active at runtime
171
+ console.log('Hermes:', global.HermesInternal != null); // should print true
172
+ ```
173
+
174
+ ### Android Release Build
175
+
176
+ ```bash
177
+ # Generate signing keystore
178
+ keytool -genkeypair -v -storetype PKCS12 \
179
+ -keystore android/app/my-release-key.keystore \
180
+ -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
181
+
182
+ # Set signing config in android/app/build.gradle.kts
183
+ # OR use environment variables (recommended for CI):
184
+ export MYAPP_RELEASE_STORE_FILE=my-release-key.keystore
185
+ export MYAPP_RELEASE_KEY_ALIAS=my-key-alias
186
+ export MYAPP_RELEASE_STORE_PASSWORD=your-password
187
+ export MYAPP_RELEASE_KEY_PASSWORD=your-password
188
+
189
+ # Build AAB (Play Store)
190
+ cd android && ./gradlew bundleRelease
191
+ # Output: android/app/build/outputs/bundle/release/app-release.aab
192
+
193
+ # Build APK (direct distribution)
194
+ cd android && ./gradlew assembleRelease
195
+ # Output: android/app/build/outputs/apk/release/app-release.apk
196
+
197
+ # Run release build on device
198
+ npx react-native run-android --mode=release
199
+ ```
200
+
201
+ ### iOS Release Build
202
+
203
+ ```bash
204
+ # Install pods
205
+ cd ios && pod install && cd ..
206
+
207
+ # Build via Xcode
208
+ open ios/MyApp.xcworkspace
209
+ # Product → Archive → Distribute App
210
+
211
+ # Build via command line (requires fastlane)
212
+ sudo gem install fastlane
213
+ cd ios && fastlane release
214
+
215
+ # TestFlight upload
216
+ cd ios && fastlane beta
217
+ ```
218
+
219
+ ## React Native vs Flutter
220
+
221
+ | Feature | React Native | Flutter |
222
+ |---------|-------------|---------|
223
+ | Language | JavaScript/TypeScript | Dart |
224
+ | UI | Native components | Custom rendering (Skia/Impeller) |
225
+ | Hot reload | Fast Refresh | Hot reload |
226
+ | Performance | Near-native (Hermes + Fabric) | Near-native (AOT compilation) |
227
+ | Ecosystem | Huge (npm) | Growing (pub.dev) |
228
+ | Web support | Via react-native-web | First-class |
229
+ | Learning curve | Low (if you know React) | Medium (Dart is less common) |
230
+
231
+ ## Common Pitfalls
232
+
233
+ | Issue | Fix |
234
+ |-------|-----|
235
+ | Metro bundler cache issues | `npx react-native start --reset-cache` |
236
+ | iOS build fails after pod install | `cd ios && pod deinstall && pod install`; check Ruby version (3.1+) |
237
+ | Android SDK not found | Set `ANDROID_HOME` env variable; verify with `npx react-native doctor` |
238
+ | Hermes not enabled | Check `hermesEnabled=true` in `android/gradle.properties`; run `pod install` |
239
+ | Release build crashes but debug works | Check ProGuard rules; add keep rules for native modules |
240
+ | App size too large | Enable Hermes; use ProGuard; split APKs by ABI |
241
+ | Network request fails in release | iOS: add App Transport Security exception in Info.plist |
242
+ | `react-native-reanimated` crash | Ensure Babel plugin is in `babel.config.js` |
243
+ | EAS build timeout | Use `--local` flag for local builds; check build logs for specific errors |
244
+ | New Architecture compatibility | Check library support at reactnative.directory; many libs still on old arch |
245
+ | "Namespace not specified" error | AGP 8.x requires `namespace` in `android/app/build.gradle`; remove `package=` from AndroidManifest.xml |
246
+ | Legacy arch modules crash (0.84+) | Old bridge modules fully removed; must use TurboModule spec files |
247
+ | JSC not available (0.81+) | Hermes is sole engine; `hermesEnabled` toggle no longer meaningful |
248
+ | iOS build rejected (0.78+) | Minimum iOS deployment target is now 16.0 (was 13.4) |
249
+ | Deep import fails (0.82+) | `require('react-native/Libraries/...')` removed; use top-level exports |
250
+ | Metro package exports break (0.79+) | Add `resolver.unstable_enablePackageExports: false` to metro.config.js to opt out |
251
+ | Jest preset not found (0.85+) | Change `preset: 'react-native'` to `preset: '@react-native/jest-preset'` |
252
+ | Firebase/Amplify build fails (0.79+) | Metro exports resolution enabled by default; see Metro config fix above |
253
+ | App Store rejected: missing Privacy Manifest | Add `PrivacyInfo.xcprivacy` to iOS project (see below) |
254
+ | `ClassNotFoundException` on release | Missing ProGuard rules — see ProGuard section below |
255
+
256
+ ## Critical: AGP 8.x Namespace Requirement
257
+
258
+ AGP 8.0+ removed `package` attribute from `AndroidManifest.xml`. You MUST use `namespace` in `build.gradle`:
259
+
260
+ ```gradle
261
+ // android/app/build.gradle
262
+ android {
263
+ namespace "com.yourapp" // REQUIRED in AGP 8.x
264
+ compileSdk 35
265
+ defaultConfig {
266
+ applicationId "com.yourapp"
267
+ minSdkVersion 24
268
+ targetSdkVersion 35
269
+ }
270
+ }
271
+ ```
272
+
273
+ ```xml
274
+ <!-- AndroidManifest.xml — REMOVE package attribute -->
275
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
276
+ <!-- no package="..." attribute -->
277
+ </manifest>
278
+ ```
279
+
280
+ ## New Architecture (Mandatory since RN 0.84)
281
+
282
+ Fabric renderer and TurboModules are **mandatory** since React Native 0.84. Legacy architecture code has been completely removed. There is no opt-out.
283
+
284
+ ```properties
285
+ # android/gradle.properties (RN 0.84+)
286
+ # newArchEnabled is no longer configurable — it's always on
287
+ hermesEnabled=true # Hermes is the sole engine (JSC removed in 0.81)
288
+ ```
289
+
290
+ **What this means:**
291
+ - ALL native modules must have TurboModule spec files
292
+ - Libraries using old `UIManager` bridge calls will NOT work
293
+ - `NativeModules` direct access deprecated — use TurboModule specs
294
+ - `requireNativeComponent` replaced by Fabric component specs
295
+ - Check library compatibility: [reactnative.directory](https://reactnative.directory)
296
+
297
+ ## ProGuard Rules (Required for Release Builds)
298
+
299
+ > ⚠️ **R8 full mode is now default** for release builds (more aggressive shrinking). Without these rules, your release build WILL crash at runtime. Legacy architecture classes removed in RN 0.84+ may require updated rules.
300
+
301
+ ```proguard
302
+ # android/app/proguard-rules.pro
303
+
304
+ # React Native Core
305
+ -keep class com.facebook.react.** { *; }
306
+ -keep class com.facebook.hermes.** { *; }
307
+ -keep class com.facebook.jni.** { *; }
308
+
309
+ # Hermes
310
+ -keep class com.facebook.hermes.unicode.** { *; }
311
+
312
+ # Native Modules (CRITICAL — R8 strips these without keep rules)
313
+ -keepnames class * extends com.facebook.react.bridge.NativeModule
314
+ -keepnames class * extends com.facebook.react.TurboModule
315
+ -keepclassmembers class * extends com.facebook.react.bridge.NativeModule {
316
+ @com.facebook.react.bridge.ReactMethod <methods>;
317
+ }
318
+
319
+ # Views
320
+ -keep class com.facebook.react.views.** { *; }
321
+ -keep class com.facebook.react.uimanager.** { *; }
322
+ -keep class com.facebook.react.animated.** { *; }
323
+
324
+ # Common third-party libraries
325
+ -keep class com.swmansion.gesturehandler.** { *; }
326
+ -keep class com.swmansion.reanimated.** { *; }
327
+ -keep class com.swmansion.rnscreens.** { *; }
328
+ -keep class com.reactnativecommunity.asyncstorage.** { *; }
329
+ -keep class com.horcrux.svg.** { *; }
330
+
331
+ # Expo modules (if using Expo)
332
+ -keep class expo.modules.** { *; }
333
+
334
+ # OkHttp
335
+ -dontwarn okhttp3.**
336
+ -keep class okhttp3.** { *; }
337
+ ```
338
+
339
+ Enable in `android/app/build.gradle`:
340
+
341
+ ```gradle
342
+ android {
343
+ buildTypes {
344
+ release {
345
+ minifyEnabled true
346
+ shrinkResources true
347
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
348
+ }
349
+ }
350
+ }
351
+ ```
352
+
353
+ ## iOS Privacy Manifest (Required for App Store)
354
+
355
+ Apple requires `PrivacyInfo.xcprivacy` since Spring 2024. Without it, your app will be rejected.
356
+
357
+ ```xml
358
+ <!-- ios/YourApp/PrivacyInfo.xcprivacy -->
359
+ <?xml version="1.0" encoding="UTF-8"?>
360
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
361
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
362
+ <plist version="1.0">
363
+ <dict>
364
+ <key>NSPrivacyTracking</key>
365
+ <false/>
366
+ <key>NSPrivacyTrackingDomains</key>
367
+ <array/>
368
+ <key>NSPrivacyCollectedDataTypes</key>
369
+ <array/>
370
+ <key>NSPrivacyAccessedAPITypes</key>
371
+ <array>
372
+ <dict>
373
+ <key>NSPrivacyAccessedAPIType</key>
374
+ <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
375
+ <key>NSPrivacyAccessedAPITypeReasons</key>
376
+ <array><string>CA92.1</string></array>
377
+ </dict>
378
+ <dict>
379
+ <key>NSPrivacyAccessedAPIType</key>
380
+ <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
381
+ <key>NSPrivacyAccessedAPITypeReasons</key>
382
+ <array><string>C617.1</string></array>
383
+ </dict>
384
+ <dict>
385
+ <key>NSPrivacyAccessedAPIType</key>
386
+ <string>NSPrivacyAccessedAPICategorySystemBootTime</string>
387
+ <key>NSPrivacyAccessedAPITypeReasons</key>
388
+ <array><string>35F9.1</string></array>
389
+ </dict>
390
+ </array>
391
+ </dict>
392
+ </plist>
393
+ ```
394
+
395
+ Add to Xcode: Drag into app group → ensure "Copy Bundle Resources" includes it.
396
+
397
+ ## Secure Signing Configuration
398
+
399
+ Never commit passwords to version control.
400
+
401
+ ```gradle
402
+ // android/app/build.gradle — secure signing
403
+ signingConfigs {
404
+ release {
405
+ storeFile file(MYAPP_RELEASE_STORE_FILE ?: System.getenv("MYAPP_RELEASE_STORE_FILE") ?: "release.keystore")
406
+ storePassword MYAPP_RELEASE_STORE_PASSWORD ?: System.getenv("MYAPP_RELEASE_STORE_PASSWORD")
407
+ keyAlias MYAPP_RELEASE_KEY_ALIAS ?: System.getenv("MYAPP_RELEASE_KEY_ALIAS")
408
+ keyPassword MYAPP_RELEASE_KEY_PASSWORD ?: System.getenv("MYAPP_RELEASE_KEY_PASSWORD")
409
+ }
410
+ }
411
+ ```
412
+
413
+ ```yaml
414
+ # GitHub Actions — decode keystore from secrets
415
+ - name: Decode Keystore
416
+ run: echo "${{ secrets.RELEASE_KEYSTORE_BASE64 }}" | base64 --decode > android/app/release.keystore
417
+ - name: Build Release
418
+ env:
419
+ MYAPP_RELEASE_STORE_FILE: release.keystore
420
+ MYAPP_RELEASE_STORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
421
+ MYAPP_RELEASE_KEY_ALIAS: ${{ secrets.KEY_ALIAS }}
422
+ MYAPP_RELEASE_KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }}
423
+ run: cd android && ./gradlew bundleRelease
424
+ ```
425
+
426
+ ## Metro Production Configuration
427
+
428
+ ```javascript
429
+ // metro.config.js
430
+ const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config');
431
+
432
+ const config = {
433
+ transformer: {
434
+ minifierConfig: {
435
+ compress: {
436
+ drop_console: true, // Remove console.log in production
437
+ },
438
+ },
439
+ },
440
+ };
441
+
442
+ module.exports = mergeConfig(getDefaultConfig(__dirname), config);
443
+ ```