Skip to content

chore(deps): upgrade to Expo SDK 56 (React Native 0.85)#87

Merged
gmaclennan merged 5 commits into
mainfrom
expo-sdk-56-spm
Jun 19, 2026
Merged

chore(deps): upgrade to Expo SDK 56 (React Native 0.85)#87
gmaclennan merged 5 commits into
mainfrom
expo-sdk-56-spm

Conversation

@gmaclennan

Copy link
Copy Markdown
Member

Context

Upgrades the module and both test apps from Expo SDK 55 → 56 (React Native 0.83.6 → 0.85.3, React 19.2, min iOS 15.1 → 16.4, Hermes v1 default, Xcode 26.4).

The original ask was to "convert to SPM + precompiled xcframeworks." Research into the SDK 56 source established that there is no supported public path for a third-party npm module to drop its podspec for a hand-authored Package.swift — Apple autolinking still requires the podspec. So this keeps the CocoaPods podspec and makes it precompile-friendly instead (see below). ios/Package.swift remains a macOS-test-only manifest.

Changes

  • Versions: expo ^56.0.12, expo-module-scripts 56.0.3, react-native 0.85.3, react 19.2.3; both test apps in lockstep.
  • iOS deployment target 15.1 → 16.4 (podspec, Package.swift .iOS(.v16), with-ios-tests plugin).
  • Precompile-friendly podspec: only source_files/exclude_files wrapped in the try_link_with_prebuilt_xcframework guard (mirroring expo-modules-core's own podspec); deps, vendored frameworks, and resources stay unconditional.
  • Android: build.gradle fallbacks compileSdk/targetSdk 34 → 35, minSdk 21 → 24; sentry-android-core 8.43 → 8.44.
  • Sentry-cocoa 9.15.0 → 9.18.0 (podspec + Package.swift + Package.resolved) following resolved @sentry/react-native 8.15.1; enforced by check-sentry-cocoa-pin.mjs.
  • expo.install.exclude for @sentry/react-native (SDK 56 tries to downgrade it to 7.x) and typescript, in both apps.
  • Drop top-level splash from the test apps (invalid in the SDK 56 config schema).
  • Minor: type-only import (verbatimModuleSyntax), worktree-safe git exclude path in eslint.config.js, unused test params removed.
  • CI: Xcode 26.3 → 26.4.

Verification

  • npm run build, npm run lint, swift test (100/100 macOS unit tests)
  • expo-doctor 21/21 in both apps/e2e and apps/example
  • ⏳ Device/runtime: Android instrumented tests + iOS runtime e2e (via BrowserStack — local sim can't run the backend) being validated alongside CI

🤖 Generated with Claude Code

Bump the module and both test apps from Expo SDK 55 to 56:
- expo ^56.0.12, expo-module-scripts 56.0.3, react-native 0.85.3, react 19.2.3
- iOS min deployment 15.1 -> 16.4 (podspec, Package.swift, with-ios-tests plugin)
- Android fallbacks compileSdk/targetSdk 34->35, minSdk 21->24
- CI Xcode 26.3 -> 26.4

Make the podspec precompile-friendly: wrap only source_files/exclude_files
in the try_link_with_prebuilt_xcframework guard (mirroring
expo-modules-core's own podspec) so a future Expo-published prebuilt
xcframework can short-circuit source compilation. Deps, vendored
frameworks, and resources stay unconditional. Note: SDK 56 has no
supported third-party SPM/precompiled-module path yet, so the CocoaPods
podspec remains the integration path.

Sentry-cocoa pin follows the resolved @sentry/react-native 8.15.1:
9.15.0 -> 9.18.0 (podspec + Package.swift + Package.resolved),
sentry-android-core 8.43 -> 8.44. SDK 56 tries to downgrade
@sentry/react-native to 7.x, so pin it (and typescript) via
expo.install.exclude in both apps. Drop top-level `splash` from the
test apps (invalid in the SDK 56 config schema).

Minor: type-only import in ComapeoCoreModule.ts (verbatimModuleSyntax),
worktree-safe git exclude path resolution in eslint.config.js, and
unused test params removed in server-helper.test.mjs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@socket-security

socket-security Bot commented Jun 19, 2026

Copy link
Copy Markdown

@socket-security

socket-security Bot commented Jun 19, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm @expo/cli is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: apps/example/package-lock.jsonnpm/expo@56.0.12npm/@expo/cli@56.1.16

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@expo/cli@56.1.16. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @react-native/debugger-frontend is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: apps/example/package-lock.jsonnpm/react-native@0.85.3npm/expo@56.0.12npm/@react-native/debugger-frontend@0.85.3

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@react-native/debugger-frontend@0.85.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @react-native/debugger-frontend is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: apps/example/package-lock.jsonnpm/react-native@0.85.3npm/expo@56.0.12npm/@react-native/debugger-frontend@0.85.3

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@react-native/debugger-frontend@0.85.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm @sentry/react-native is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: apps/example/package-lock.jsonnpm/@sentry/react-native@8.15.1

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/@sentry/react-native@8.15.1. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm es-abstract is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: package-lock.jsonnpm/expo-module-scripts@56.0.3npm/es-abstract@1.24.2

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/es-abstract@1.24.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm js-yaml is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: apps/example/package-lock.jsonnpm/expo@56.0.12npm/js-yaml@4.2.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/js-yaml@4.2.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm yargs is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: apps/example/package-lock.jsonnpm/react-native@0.85.3npm/babel-preset-expo@56.0.15npm/expo@56.0.12npm/yargs@17.7.3

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/yargs@17.7.3. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

The macos-15 runner image tops out at Xcode 26.3, so the 26.4 select
step failed immediately (`invalid developer directory`). Expo SDK 56
requires Xcode >= 26.4, which only the macos-26 image provides
(ships 26.0.1 through 26.5, incl. 26.4.1). Move all iOS jobs to
macos-26 and pin Xcode_26.4.1. Refresh the now-stale runner/Xcode and
sentry-cocoa (9.18.0) comments.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gmaclennan gmaclennan marked this pull request as ready for review June 19, 2026 12:49
gmaclennan and others added 3 commits June 19, 2026 14:06
The E2E release builds (assembleRelease / archive) failed at the
"Bundle React Native code and images" Metro step with
`Cannot find module 'babel-preset-expo'` on both iOS and Android. Under
SDK 55 babel-preset-expo was hoisted to each app's node_modules root;
the SDK 56 install left only a stale nested copy
(expo/node_modules/babel-preset-expo@55.0.18), which Metro's
babel.config.js (`presets: ['babel-preset-expo']`) can't resolve from
the app root. Add it as a direct dep (~56.0.0) in both apps. Debug
builds didn't surface this because they don't run the release JS bundle.

Verified locally: `expo export --platform ios` for apps/e2e now bundles
746 modules to Hermes bytecode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… SDK 56)

expo-module-scripts@56 turned `expo-module prepare` into a noop
("Run `expo-module configure` once per package manually instead"), so
the `prepare` lifecycle no longer compiled `build/`. The E2E apps
resolve `@comapeo/core-react-native` (via Metro `extraNodeModules`) to
this package's `build/index.js`; with `build/` never generated at
`npm install` time in CI, the bundle resolved the module to empty
exports, so `comapeo` / `comapeoServicesClient` came back `undefined`
at runtime and every map-server / basic spec failed (the app didn't
crash — the imports were simply undefined).

Other CI jobs were unaffected: android-tests / ios-tests install with
`--ignore-scripts` (no `prepare`, no `build/` needed — they exercise
native code), and the local release run passed only because `build/`
had been compiled by an explicit `npm run build`.

Switch `prepare` to `expo-module build`. This also fixes publishing,
which under the noop would otherwise have shipped without `build/`.

Verified: `rm -rf build && npm install` now regenerates build/index.js
and build/ComapeoCoreModule.js with the IPC client factories.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… 0.85

Two regressions introduced by the SDK 55->56 (RN 0.83->0.85) bump; both
paths were identical on main and worked there. They only surface in the
E2E release bundle (debug builds and the swift/instrumented suites don't
bundle the module's JS).

1. Metro resolution. The example/e2e apps resolved the workspace module
   via `extraNodeModules: { '@comapeo/core-react-native': '../..' }`.
   RN 0.85's Metro no longer honours `extraNodeModules` pointing at a
   package that defines an `exports` map — it resolves to an empty module,
   so every export (`comapeo`, `comapeoServicesClient`, ...) read back
   `undefined` and every spec failed with "Cannot read property X of
   undefined". Replace the hack with an idempotent node_modules symlink
   created at metro-config load, so Metro resolves the package through the
   normal node_modules path (which honours `exports`). Disabling package
   exports is not an option — `@comapeo/ipc/client.js` needs its exports
   map to resolve.

2. type-fest. `import { type JsonValue }` compiles (verbatimModuleSyntax)
   to `import {} from "type-fest"` — a runtime import of a types-only
   package with no resolvable `main`. SDK 55's Metro tolerated it; RN
   0.85's stricter resolver errors. Use `import type` so tsc elides it.

Verified: apps/e2e release build + the real maestro flow on an emulator
now bundles the full module (1335 vs 743 modules) and reports
`jasmine done: passed` with zero spec failures.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gmaclennan gmaclennan merged commit c3f959f into main Jun 19, 2026
12 checks passed
@gmaclennan gmaclennan deleted the expo-sdk-56-spm branch June 19, 2026 15:43
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