CAMDOM -- Stack Migrations & Build Evolution
Complete evolution of the technology stack: React Native versions, Expo SDK, JSI migration, TurboModules, build system, patches, CI/CD.
CAMDOM -- Stack Migrations & Build Evolution
Repository:
p4bventures/condom-appTotal commits: 429 (2024-06-06 to 2025-11-16) Package name:condom-app(npm) /com.billyboy.condomapp(Android) /innocean-camdom(Expo slug) Current version:4.44.44(app.json) /7.7.7(package.json)
1. Timeline Overview
2024-06-06 Initial commit ........... Expo 51, RN 0.74.2, React 18.2.0, Reanimated 3.x
2024-06-16 Pipeline added .......... EAS Build, GitHub Actions v1
2024-07-01 Skia + Reanimated V3 .... @shopify/react-native-skia ^1.3.7
2024-07-01 Native Modules defined .. Expo Modules API (JSI) for BLE
2024-07-07 iOS/Android native modules BLE Manager (Swift + Kotlin)
2024-07-10 BLE cross-platform ...... Android + iOS BLE working
2024-07-29 V1.0.0 Android .......... Firebase, Google Auth, Apple Auth added
2024-08-02 V2.0.0 .................. Peripheral manager feature branch merged
2024-08-04 V2.x rapid iteration .... Expo Updates configured, CI/CD stabilized
2024-08-18 Unistyles introduced .... react-native-unistyles ^2.9.1
2024-09-01 Android SDK 34 .......... compileSdk/targetSdk bumped
2024-09-05 V3.x series ............. Alarm/disconnection rework, session replay
2024-09-20 V3.33.0 ................. Last Expo 51 release before naming reset
2024-10-11 CamdomApp 1.0.0 ......... Version naming reset (CamdomApp era)
2024-10-15 Google login removed ..... Firebase auth stripped
2024-11-07 1.0.2 ................... itusexexempt encryption added
2025-01-31 1.2.0 ................... Package encryption
2025-06-09 Android versions update .. compileSdk 36, Gradle update, expo-modules-core patch
2025-10-06 Workbranch merge ......... Version bumps to 3.34.0 (Expo 51 still)
2025-11-12 **MAJOR MIGRATION** ...... Expo 54, RN 0.82, React 19, Reanimated 4
2025-11-16 Migration stabilized ..... "it builds fuck", final fixes
2. React Native Version History
| Date | Commit | RN Version | React Version | Expo SDK | Notes |
|---|---|---|---|---|---|
| 2024-06-06 | 27d64d6 | 0.74.2 | 18.2.0 | ~51.0.11 | Initial scaffold (Expo create-template) |
| 2024-07-01 | b1f54f3 | 0.74.2 | 18.2.0 | ~51.0.11 | + Skia, ReanimatedV3, GestureHandler |
| 2024-08-02 | 6078d0f | 0.74.3 | 18.2.0 | ~51.0.11 | V2.0.0 - Peripheral manager merged |
| 2024-08-18 | 73b7478 | 0.74.3 | 18.2.0 | ~51.0.24 | + Unistyles ^2.9.1 |
| 2024-11-07 | bfc816c | 0.74.3 | 18.2.0 | ~51.0.24 | Stable Expo 51 build |
| 2025-06-09 | 010d6d7 | 0.74.3 | 18.2.0 | ~51.0.24 | Android SDK 36, still Expo 51 |
| 2025-10-06 | c82e02d | 0.74.3 | 18.2.0 | ~51.0.24 | Last pre-migration release |
| 2025-11-12 | 231cbb5 | 0.82.1 | 19.1.1 | ^54.0.23 | Big bang migration |
| 2025-11-16 | 23ef990 | 0.82.1 | 19.1.1 | ^54.0.23 | Migration stabilized |
Key Observations
- The project stayed on RN 0.74 + Expo 51 for 17 months (Jun 2024 -- Nov 2025).
- The migration to RN 0.82 + Expo 54 happened in a single burst over 4 days (Nov 12--16, 2025).
- React jumped from 18.2.0 to 19.1.1 (major version bump).
- The commit messages during migration tell the story:
wip: almost alive babe->working shit->yaaay fita!->it builds fuck->final bitch - wip->yaaay olddd.
3. Expo SDK Evolution
Phase 1: Expo 51 (Jun 2024 -- Nov 2025)
Initial SDK 51.0.11 with minimal plugins. Grew to include:
{
"plugins": [
"expo-router",
"expo-font",
"expo-localization",
"react-native-ble-plx",
"expo-splash-screen",
"expo-build-properties",
"expo-haptics",
"expo-updates"
]
}
Removed during cleanup: expo-status-bar, expo-system-ui, expo-web-browser, expo-dev-client, expo-updates.
Phase 2: Expo 54 (Nov 2025 -- present)
Full SDK jump. Module versions jumped to Expo 54-compatible:
| Module | Expo 51 | Expo 54 |
|---|---|---|
| expo | ~51.0.24 | ^54.0.23 |
| expo-router | ~3.5.20 | ~6.0.14 |
| expo-av | ~14.0.6 | ~16.0.7 |
| expo-font | ~12.0.9 | ~14.0.9 |
| expo-haptics | ~13.0.1 | ~15.0.7 |
| expo-constants | ~16.0.2 | ~18.0.10 |
| expo-splash-screen | ~0.27.5 | ~31.0.10 |
| expo-localization | ~15.0.3 | ~17.0.7 |
| expo-linking | ~6.3.1 | ~8.0.8 |
| expo-build-properties | ~0.12.4 | ~1.0.9 |
4. JSI Migration: Bridge to JavaScript Interface
Why JSI Was Needed
CAMDOM is a BLE (Bluetooth Low Energy) consent protection app. The core loop requires:
- Real-time BLE peripheral advertising and central scanning
- Sub-second bidirectional packet exchange between paired devices
- Native AppleScript/Alarm integration on iOS
- Background BLE operation with WakeLock on Android
The React Native Bridge architecture adds ~5-10ms per native call due to JSON serialization. For BLE state machines handling 60-second polling intervals with alarm triggers, this latency compounds and causes disconnection race conditions.
The Custom BLE Manager Module (Expo Modules API / JSI)
Located at modules/ble-manager/, this is a custom Expo Module (not a TurboModule, not a Bridge module) that uses the Expo Modules API with JSI bindings.
Structure:
modules/ble-manager/
expo-module.config.json # Platform registration
index.ts # requireNativeModule('BleManager')
src/
BleManager.ts # JS API surface
BleManagerModule.ts # requireNativeModule bridge
BlePeripheralManager.ts # Peripheral API
Events.types.ts # Type definitions
Utils.ts # Helpers
android/
build.gradle # Android build (compileSdk 36)
src/main/java/p4b/modules/blemanager/
BleManagerModule.kt # Kotlin Expo Module
BleManager.kt # Central manager logic
BlePeripheralManager.kt # Peripheral logic
ios/
BleManagerModule.swift # Swift Expo Module
BlePeripheralManager.swift
BleManager.podspec
Key JS interface (modules/ble-manager/src/BleManagerModule.ts):
import {requireNativeModule} from 'expo-modules-core';
// It loads the native module object from the JSI or falls back to
// the bridge module (from NativeModulesProxy) if the remote debugger is on.
export default requireNativeModule('BleManager');
This explicitly uses requireNativeModule which loads via JSI, bypassing the Bridge entirely. The fallback to NativeModulesProxy only activates during remote debugging.
Module registration (expo-module.config.json):
{
"platforms": ["ios", "android"],
"ios": { "modules": ["BleManagerModule"] },
"android": { "modules": ["p4b.modules.blemanager.BleManagerModule"] }
}
Evolution of Native Module Architecture
| Phase | Date | Architecture | Commit |
|---|---|---|---|
| Definition | 2024-07-01 | 91c4be0 - Native Modules definition | Initial Expo Modules API types |
| Android config | 2024-07-08 | c986dda - Android native module config | Kotlin module registration |
| iOS config | 2024-07-08 | 5b98522 / 7a4664f - iOS native module config | Swift module registration |
| BLE working | 2024-07-10 | 681eb80 - 0.1.6 ANDROID & iPhone BLE | Cross-platform BLE verified |
| Android scan | 2024-07-22 | 43d273a - Android Scanning and connect | BLE scan + connect flow |
| Android 100% | 2024-07-22 | 68c2810 - Android Finally 100% | Full BLE peripheral + central |
| Peripheral merged | 2024-08-02 | 6078d0f - V2.0.0 | Peripheral manager feature branch |
| New Arch enabled | 2025-11-12 | 231cbb5 | TurboModules + Fabric enabled |
| Nitro Modules added | 2025-11-16 | 23ef990 | react-native-nitro-modules ^0.31.4 |
5. TurboModules / New Architecture
Activation
New Architecture was enabled during the Expo 54 migration (Nov 2025):
android/gradle.properties:
newArchEnabled=true
hermesEnabled=true
edgeToEdgeEnabled=true
MainActivity.kt references:
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
The activity delegates Fabric rendering via fabricEnabled flag from DefaultNewArchitectureEntryPoint.
MainApplication.kt uses the new React Native 0.82 initialization pattern:
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.common.ReleaseLevel
class MainApplication : Application(), ReactApplication {
override fun onCreate() {
super.onCreate()
DefaultNewArchitectureEntryPoint.releaseLevel = ReleaseLevel.STABLE
loadReactNative(this)
ApplicationLifecycleDispatcher.onApplicationCreate(this)
}
}
This is the RN 0.82+ ReactNativeApplicationEntryPoint pattern, replacing the older SoLoader.init() approach. The ReleaseLevel.STABLE flag indicates full New Architecture adoption.
ReactHost (New Architecture)
override val reactHost: ReactHost by lazy {
getDefaultReactHost(
context = applicationContext,
packageList = PackageList(this).packages,
jsMainModulePath = ".expo/.virtual-metro-entry",
useDevSupport = BuildConfig.DEBUG
)
}
The jsMainModulePath = ".expo/.virtual-metro-entry" is the Expo 54 virtual entry point pattern.
Nitro Modules
Added in the final migration commit (23ef990): react-native-nitro-modules: ^0.31.4. This provides高性能 native bindings as an alternative to TurboModules for specific use cases.
ProGuard Rules (TurboModules)
-keep class com.swmansion.reanimated.** { *; }
-keep class com.facebook.react.turbomodule.** { *; }
Both Reanimated and TurboModule classes are preserved from R8 minification.
6. Build System
Gradle Configuration
Root android/build.gradle:
ext {
buildToolsVersion = "36.0.0"
minSdkVersion = 24
compileSdkVersion = 36
targetSdkVersion = 36
ndkVersion = "27.1.12297006"
}
App android/app/build.gradle:
android {
buildToolsVersion "36.0.0"
compileSdk 36
defaultConfig {
multiDexEnabled true
applicationId 'com.billyboy.condomapp'
minSdkVersion 24
targetSdkVersion 36
versionCode 7777777
versionName "7.7.7"
}
}
The versionCode/versionName in build.gradle are placeholder values -- actual versions are injected by scripts/version_bumper.js at build time.
Gradle Wrapper: gradle-8.14.3-bin.zip
Kotlin Gradle Plugin: Applied via classpath('org.jetbrains.kotlin:kotlin-gradle-plugin')
Expo CLI Integration in Gradle
react {
entryFile = file(["node", "-e", "require('expo/scripts/resolveAppEntry')", ...].execute().text.trim())
cliFile = new File(["node", "--print", "require.resolve('@expo/cli', ...)"].execute().text.trim())
bundleCommand = "export:embed"
autolinkLibrariesWithApp()
}
The build uses Expo CLI (@expo/cli) for bundling instead of the standard React Native CLI. The bundleCommand = "export:embed" ensures Metro configuration from Expo is respected.
Hermes Engine
Enabled by default:
if (hermesEnabled.toBoolean()) {
implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
JSC fallback configured as io.github.react-native-community:jsc-android:2026004.+.
Metro Bundler
Minimal configuration -- delegates entirely to Expo defaults:
const {getDefaultConfig} = require('expo/metro-config');
const config = getDefaultConfig(__dirname);
module.exports = config;
Babel
presets: ['babel-preset-expo'],
plugins: [
['react-native-unistyles/plugin', { root: 'app' }],
'react-native-reanimated/plugin',
]
Reanimated plugin is last (required by Reanimated docs). Unistyles Babel plugin processes files under app/.
Expo Autolinking
// settings.gradle
plugins {
id("com.facebook.react.settings")
id("expo-autolinking-settings")
}
expoAutolinking.useExpoModules()
expoAutolinking.useExpoVersionCatalog()
Uses Expo's own autolinking system, not the community @react-native-community/cli autolinking.
7. Patches Directory
expo-modules-core@1.12.24.patch
File: patches/expo-modules-core@1.12.24.patch
Problem: Expo Modules Core's PermissionsService.kt had a null-safety issue on Android when targeting SDK 34+. The requestedPermissions field from PackageInfo became nullable in newer Android API levels.
The fix (commit 672821d, 2025-06-09):
- return requestedPermissions.contains(permission)
+ return requestedPermissions?.contains(permission) ?: false
Why it was needed: When compileSdkVersion was bumped to 36, the Android SDK's PackageInfo.requestedPermissions field changed from String[] (non-null in Java) to String[]? (nullable in Kotlin). The Expo Modules Core library had not yet updated for this change, causing a Kotlin compilation error: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver.
Impact: Without this patch, the entire Android build would fail. The patch was applied via pnpm patch expo-modules-core (standard pnpm patching mechanism).
Commit: 672821d "add patch to expo-modules-core-permissions due to kotlin check"
8. Android SDK Evolution
| Date | Commit | compileSdk | targetSdk | minSdk | buildTools | Kotlin/Gradle | Notes |
|---|---|---|---|---|---|---|---|
| 2024-06-06 | 27d64d6 | 34 | 34 | 24 | 34.0.0 | Kotlin plugin | Initial Expo prebuild |
| 2024-09-01 | 3bc4163 | 34 | 34 | 24 | 34.0.0 | Same | Explicit SDK 34 bump commit |
| 2025-06-09 | 010d6d7 | 36 | 36 | 24 | 36.0.0 | Updated | "update app to newer android versions" |
| 2025-11-12 | 231cbb5 | 36 | 36 | 24 | 36.0.0 | Same | Expo 54 migration |
Key Changes
- minSdkVersion 24 (Android 7.0 Nougat) -- maintained throughout the entire project lifecycle. This is the minimum for BLE peripheral mode on Android.
- NDK version:
27.1.12297006 - multiDexEnabled:
true-- required for Firebase + all native modules - Edge-to-edge: Enabled in the final migration (
edgeToEdgeEnabled=truein gradle.properties,edgeToEdgeEnabled: truein app.json)
9. iOS Configuration
Podfile
The iOS configuration uses Expo's managed Podfile approach. No custom Podfile modifications were found in the repository -- the Podfile is generated by expo prebuild.
Entitlements
No .entitlements files were found in the repository. iOS entitlements are managed through Expo's prebuild system and the app.json configuration.
Background Modes
BLE background operation is configured via the react-native-ble-plx plugin in app.json:
["react-native-ble-plx", {
"isBackgroundEnabled": true,
"modes": ["peripheral", "central"],
"bluetoothAlwaysPermission": "Allow $(PRODUCT_NAME) to connect to other devices..."
}]
The isBackgroundEnabled: true setting triggers Expo prebuild to add bluetooth-central and bluetooth-peripheral background modes to the iOS Info.plist.
10. CI/CD
GitHub Actions
The CI/CD pipeline evolved through multiple iterations:
Phase 1 (Jul 2024): android_build_googleplay.yml -- initial EAS Build workflow
Phase 2 (Aug 2024): EAS Update configured (583bcb0), Expo Updates auto-publish
Phase 3 (Sep 2024): AppCenter deploy added (b5eab2e)
Phase 4 (Jun 2025): New main.yml created (4e07cd9), modernized CI
Phase 5 (Oct 2025): Workbranch updates (b75f182)
Version Bumping Strategy
Two-mode version bumper at scripts/version_bumper.js:
Dev mode (pnpm version:android:dev):
- Auto-increments
minorversion (e.g.,4.44.44->4.45.44) - Increments
versionCodeby 1 - Non-interactive
Final mode (pnpm version:android:final):
- Interactive wizard -- prompts for
versionNameandversionCode - Validates
versionCode > current versionCode(Play Store requirement) - Blocks build if validation fails
Build Scripts
{
"android:fast": "pnpm expo run:android -- --active-arch-only -PreactNativeArchitectures=arm64-v8a",
"build:android": "cd android && ./gradlew bundleRelease && cd ..",
"release:android": "pnpm build:android && pnpm check:sdk-details && pnpm open-aab-folder",
"release:android:dev": "pnpm version:android:dev && pnpm build:android && pnpm check:sdk-details && pnpm open-aab-folder",
"release:android:final": "pnpm version:android:final && pnpm build:android && pnpm check:sdk-details && pnpm open-aab-folder"
}
The android:fast script builds only for arm64-v8a (development device), skipping x86/x86_64/armeabi-v7a architectures. The check:sdk-details script validates the output AAB file.
11. Dependency Highlights
BLE & Connectivity
| Package | Version | Role | Evolution |
|---|---|---|---|
react-native-ble-plx | ^3.5.0 | BLE central scanning + connection | ^3.2.1 -> ^3.5.0 (Expo 54 compat) |
Custom ble-manager module | 0.6.0 | BLE peripheral advertising (JSI) | Expo Modules API, never changed architecture |
react-native-permissions | ^4.1.5 | Runtime permission handling | Same version throughout |
State & Storage
| Package | Version | Role | Evolution |
|---|---|---|---|
react-native-mmkv | 4.0.0 | Key-value storage (fast) | ^2.12.2 -> 4.0.0 (Expo 54 compat) |
react-native-volume-manager | ^2.0.8 | System volume control | Added in v2.18 era |
UI & Animation
| Package | Version | Role | Evolution |
|---|---|---|---|
react-native-reanimated | ~4.1.5 | Smooth animations, layout animations | ~3.10.1 -> ~4.1.5 (major version bump) |
react-native-gesture-handler | ~2.28.0 | Touch gesture system | ~2.16.1 -> ~2.28.0 |
@shopify/react-native-skia | 2.3.10 | Canvas rendering (background balls) | ^1.3.7 -> ^1.2.3 -> 2.3.10 (major bump) |
react-native-unistyles | 3.0.17 | Runtime theming/styles | ^2.9.1 -> 3.0.17 (major version bump) |
react-native-screens | ~4.18.0 | Native screen containers | 3.31.1 -> ~4.18.0 (major bump) |
Navigation
| Package | Version | Role | Evolution |
|---|---|---|---|
expo-router | ~6.0.14 | File-based routing | ~3.5.20 -> ~6.0.14 (major bump) |
@react-navigation/native | ^7.1.19 | Navigation primitives | ^6.0.2 -> ^7.1.19 (major bump) |
Audio & Haptics
| Package | Version | Role | Evolution |
|---|---|---|---|
expo-av | ~16.0.7 | Audio playback (alarm sounds) | ~14.0.6 -> ~16.0.7 |
expo-haptics | ~15.0.7 | Haptic feedback | ~13.0.1 -> ~15.0.7 |
react-native-snackbar | ^2.6.2 | Toast notifications | Same version throughout |
Device Info & Utilities
| Package | Version | Role | Evolution |
|---|---|---|---|
react-native-device-info | ^11.1.0 | Device metadata | Same version throughout |
react-native-nitro-modules | ^0.31.4 | High-perf native bindings | Added in Expo 54 migration |
i18next / react-i18next | ^23.12.2 / ^15.0.0 | Internationalization | Same versions throughout |
Removed During Migration
| Package | Last Seen | Reason |
|---|---|---|
react-native-firebase/* | Expo 51 era | Firebase auth removed (Oct 2024) |
@react-native-google-signin/google-signin | Expo 51 era | Google login removed (Oct 2024) |
@invertase/react-native-apple-authentication | Expo 51 era | Apple auth removed |
expo-dev-client | Expo 51 era | No longer needed in Expo 54 |
expo-status-bar | Expo 51 era | Deprecated/merged |
expo-system-ui | Expo 51 era | Deprecated/merged |
expo-web-browser | Expo 51 era | Not used |
react-native-awesome-slider | Expo 51 era | Replaced or removed |
react-native-keyboard-controller | Expo 51 era | Replaced or removed |
react-native-quick-base64 | Expo 51 era | Replaced or removed |
react-native-get-random-values | Expo 51 era | Polyfill no longer needed |
expo-updates | Expo 51 era | Removed from dependencies |
12. Migration Challenges
Expo 51 -> 54 Migration (Nov 12--16, 2025)
This was the largest migration in the project's history. Evidence from commit messages and diffs:
Day 1 (Nov 12) -- "the painful day":
4aa6cfe"version bumps" -- Initial dependency updatesaeaf642"bump one version yaay" -- Version bump after first successful change231cbb5"working shit" -- First build that compiledd822683"yaaay fita!" -- Breakthrough moment5efba89"update splash" -- expo-splash-screen config changed (0.27 -> 31.x)b19cdc4"final bitch - wip" -- Still fixing issuesd94d64c"it builds fuck" -- Finally building
Day 2 (Nov 14):
1ac485c"latex" -- Unknown but likely asset-related
Day 3 (Nov 16) -- "cleanup day":
259fb54"idk" -- Confusion during cleanupbef7ef5"update versions" -- Version reconciliation57487ad"betterscripts" -- Script improvementsc379064"android 6" -- Android build number 68db976f"wip" ->3c21891"yup" ->988ca99"idk bro" ->23ef990"yaaay olddd" -- Final stabilization
What broke:
- Reanimated 3 -> 4: Major API changes. The project was using Reanimated 3.10.1; Reanimated 4 has breaking changes in layout animations and shared element transitions.
- Unistyles 2 -> 3: Major version bump with new plugin API (
react-native-unistyles/pluginwithrootoption). - Skia 1.x -> 2.x: Complete API overhaul for
@shopify/react-native-skia. - expo-splash-screen 0.27 -> 31.x: The splash screen API changed dramatically (now
SplashScreenManager.registerOnActivity(this)pattern in Kotlin). - React 18 -> 19: New rendering behavior, potential breaking changes in hooks.
- expo-router 3 -> 6: File-based routing API changes.
- MMKV 2.x -> 4.0: Storage API changes.
- MainApplication.kt rewrite: New
ReactNativeApplicationEntryPoint.loadReactNative()pattern replacedSoLoader.init(). - Firebase/Google auth removal: The entire auth stack was stripped, simplifying the dependency tree but requiring code removal.
- expo-modules-core patch: The null-safety fix for Android SDK 36 compatibility was carried forward.
Earlier Migration Challenges
V1 -> V2 (Jul-Aug 2024): The Peripheral Manager feature branch (feature/peripheral-manager) required three Android build fix commits (0c38e44, 45dc77c, 63af0dd) before merging. BLE peripheral mode on Android required careful handling of BluetoothGattServer lifecycle.
Android SDK 34 bump (Sep 2024): Required version matching across all CI steps (51c5d7c "Ensure Android Versions matching in all steps + SetupGradle Action before using gradle").
Expo Updates crashes (Sep 2024): Multiple crash-fix iterations: ExoPlayer crash (a8c0c8c), Android crash (aa21d5a), Expo Updates on Android (ff44afa). The rapid 2.x -> 3.x version progression (v2.47.3 -> v3.33.0 in one day) indicates aggressive hotfixing.
13. Current State Summary
| Aspect | Value |
|---|---|
| React Native | 0.82.1 |
| React | 19.1.1 |
| Expo SDK | 54 |
| TypeScript | ~5.9.3 |
| Package Manager | pnpm 9.6.0 |
| Android compileSdk | 36 |
| Android targetSdk | 36 |
| Android minSdk | 24 |
| Gradle | 8.14.3 |
| NDK | 27.1.12297006 |
| New Architecture | Enabled (Fabric + TurboModules) |
| Hermes | Enabled |
| Edge-to-edge | Enabled |
| JSI | Custom BLE Manager (Expo Modules API) |
| Nitro Modules | ^0.31.4 (added Nov 2025) |
| App version | 4.44.44 (app.json) / 7.7.7 (build.gradle placeholder) |
| Package ID | com.billyboy.condomapp |
| Patches | expo-modules-core@1.12.24.patch (null-safety fix) |
| CI/CD | GitHub Actions (main.yml) |
| Version management | Custom version_bumper.js (dev + final modes) |
References
- Commit
27d64d6: Initial commit (2024-06-06) - Commit
91c4be0: Native Modules definition (2024-07-01) - Commit
6078d0f: V2.0.0 - Peripheral manager merged (2024-08-02) - Commit
3bc4163: Android SDK 34 bump (2024-09-01) - Commit
7c1ec63: CamdomApp 1.0.0 version reset (2024-10-11) - Commit
672821d: expo-modules-core patch (2025-06-09) - Commit
010d6d7: Android SDK 36 update (2025-06-09) - Commit
231cbb5: Expo 54 migration begins (2025-11-12) - Commit
d94d64c: "it builds fuck" - first successful build (2025-11-12) - Commit
23ef990: Migration stabilized (2025-11-16)
This document is a living reference. As new migrations occur, update the timeline and tables accordingly.