Skip to content

Expo SDK upgrade: 43 → 57 (bundles; needs device verification) - #45

Open
ikidnapmyself wants to merge 27 commits into
masterfrom
feature/expo-sdk-upgrade
Open

Expo SDK upgrade: 43 → 57 (bundles; needs device verification)#45
ikidnapmyself wants to merge 27 commits into
masterfrom
feature/expo-sdk-upgrade

Conversation

@ikidnapmyself

@ikidnapmyself ikidnapmyself commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Goal

Upgrade from Expo SDK 43 (RN 0.64, React 17, parked since Jan 2022) to the latest SDK 57 (RN 0.86, React 19.2.3).

Strategy: staged in-place — 43 → 505257, verifying a clean expo export (Metro bundle) at each step. Full log: EXPO_UPGRADE_PLAN.md.

⚠️ Draft. All three phases bundle cleanly and expo-doctor is 20/20, but the app has not yet been run on a device/simulator. Bundling ≠ runtime/visual correctness — needs a dev build pass before merge.

Phase 1 — SDK 50 ✅

  • Node 20 via .nvmrc (fnm); manifest → SDK 50; removed dead react-navigation@4 trio; @react-navigation/* v5 → v6
  • expo-random dropped (unused); Linking.makeUrlcreateURL; reanimated Babel plugin
  • All 28 NativeBase v2 files → gluestack-ui; icons → @expo/vector-icons; root under GluestackUIProvider
  • @babel/plugin-transform-class-static-block for gluestack react-aria deps

Phase 2 — SDK 52 ✅

  • RN 0.76.9 / React 18.3.1; New Architecture default-on
  • expo-barcode-scanner (removed SDK 51) → expo-camera CameraView in QRReaderScreen
  • React Navigation v6 → v7; gitignore/untrack .expo

Phase 3 — SDK 57 ✅

  • Node 22 via .nvmrc; RN 0.86 / React 19.2.3
  • Reanimated 3 → 4 (react-native-worklets/plugin + react-native-worklets)
  • expo-splash-screen plugin (splash moved out of app.json root); explicit @expo/vector-icons
  • expo-doctor 20/20; expo export (iOS) bundles

Remaining before merge

  • Run on iOS + Android (dev build); smoke-test auth, QR add-contact, threads/echo, navigation
  • Visual pass on every screen (UI-lib swap changed rendering)
  • Android edge-to-edge (SDK 53+) review; revalidate socket.io-client/laravel-echo vs server

Review notes

  • NativeBase → gluestack is a visual change; mapping table in EXPO_UPGRADE_PLAN.md.
  • components/EchoServer.js imports non-existent ../services/* paths — appears dead; flagged.
  • gluestack-ui v1 on React 19 / New Arch bundles fine but is unverified at runtime.

🤖 Generated with Claude Code

ikidnapmyself and others added 4 commits July 14, 2026 22:22
- Pin Node 20 via .nvmrc (fnm); drop stale SDK-43 yarn.lock
- Bump manifest to SDK 50 (RN 0.73, React 18); expo install --fix aligned
- Remove dead legacy react-navigation@4 trio; @react-navigation/* v5->v6
- expo-random dropped (unused) -> expo-crypto available; masked-view + pager-view for nav v6
- Babel: add react-native-reanimated/plugin
- App root wrapped in GluestackUIProvider; Linking.makeUrl -> createURL
- Begin NativeBase v2 -> gluestack-ui: LoadingScreen, Loading, CustomHeader (reference pattern)
- EXPO_UPGRADE_PLAN.md with staged plan + component mapping table

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Convert all 28 NativeBase files to gluestack-ui + @expo/vector-icons
- react-navigation v5 -> v6 tabBarIcon API (tintColor -> color)
- Fix expo-linking makeUrl -> createURL; wrap root in GluestackUIProvider
- Add @babel/plugin-transform-class-static-block for gluestack react-aria deps
- Delete dead 'BottomTabs copy.js'
- expo-doctor 16/16 clean; expo export (iOS) bundles successfully

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Bump to SDK 52; expo install --fix aligned all deps
- expo-barcode-scanner (removed SDK 51) -> expo-camera CameraView in QRReaderScreen
- React Navigation v6 -> v7
- gitignore .expo/; untrack .expo dir
- expo-doctor 18/18 clean; expo export (iOS) bundles

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Node 22 pinned via .nvmrc; bump to SDK 57; expo install --fix aligned
- Reanimated 3 -> 4: babel plugin -> react-native-worklets/plugin; install react-native-worklets
- Install expo-splash-screen; move splash config from app.json root to plugin
- Add explicit @expo/vector-icons dep (no longer transitive in SDK 57)
- expo-doctor 20/20 clean; expo export (iOS) bundles

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ikidnapmyself ikidnapmyself changed the title Expo SDK upgrade: 43 → 57 (staged, in progress) Expo SDK upgrade: 43 → 57 (bundles; needs device verification) Jul 15, 2026
ikidnapmyself and others added 22 commits July 16, 2026 19:22
…ver settings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pusher-js/react-native pulls in @react-native-community/netinfo and breaks
web bundling; the default pusher-js entry works on web and in Expo/RN via the
global WebSocket + global.Pusher shim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
connector.socket only exists for the socket.io broadcaster; the Reverb
(Pusher) connector exposes connector.pusher, so connector.socket was undefined
and .connected threw on every post-login screen. connectionStatus() is the
broadcaster-agnostic public API.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
On native, Metro resolves pusher-js to its react-native build, which imports
netinfo. Installing it lets iOS/Android bundle; web keeps using the browser
build (no netinfo). Installed via expo install for SDK 57 compatibility.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expo Go can't run SDK 57 on-device, so add expo-dev-client and an eas.json with
development (device, internal distribution) and development-simulator profiles
to build a custom dev client that embeds SDK 57 native modules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pusher-js's native build exports the class as `.Pusher` (web exports it as the
default), so `import Pusher from 'pusher-js'` was an object, not a constructor,
crashing Echo construction with "Object cannot be used as a constructor". Unwrap
`.Pusher ?? .default ?? module` so it works on both platforms.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fetch the user profile after login (GetProfile) and store { access_token,
  user } so screens reading userState.user.id work.
- Guard the App.js restore path/render on user.user?.id so a stale session
  routes to login instead of crashing.
- Hide the native splash once the initial auth check resolves (SDK 50+ no
  longer auto-hides).
- Send an OAuth clientId (from config) and an absolute swinn:// redirect URI so
  the token redirect deep-links back to the app instead of 404ing on the API host.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- app.json: scheme "swinn" + iOS bundleIdentifier me.swinn.app (native config
  for deep-link redirects and dev builds).
- config/env.js: expose auth.clientId from EXPO_PUBLIC_OAUTH_CLIENT_ID.
- .env.example: document the new var.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ikidnapmyself
ikidnapmyself marked this pull request as ready for review July 18, 2026 19:46
- patch-package: capture the expo-modules-jsi Swift fix (abs -> .magnitude,
  needed to compile under Xcode 26.3) as patches/expo-modules-jsi+57.0.3.patch,
  re-applied via a postinstall hook.
- yarn.lock: remove the corrupt `name string-width-cjs` / `strip-ansi-cjs` /
  `wrap-ansi-cjs` overrides so string-width/strip-ansi/wrap-ansi install under
  their canonical names — fixes `Cannot find module 'string-width'` from
  wrap-ansi (Expo CLI) on a fresh install.

Verified: pristine `rm -rf node_modules && yarn install` yields node_modules/
string-width, wrap-ansi resolves it, the Swift patch is applied, and
`expo start` boots without crashing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant