feat(expo): upgrade to Expo SDK 56 / React Native 0.85#2581
Conversation
- expo 55 → 56.0.9, react-native 0.83 → 0.85.3
- all expo-* packages updated to SDK 56 equivalents
- migrate @react-navigation/* imports to expo-router entry points (SDK 56 breaking change)
- remove @react-navigation/{native,elements,bottom-tabs,drawer} direct dependencies
- fix expo-navigation-bar API: setButtonStyleAsync/setPositionAsync/setBackgroundColorAsync removed, replaced with synchronous setStyle
- migrate splash config from deprecated top-level ExpoConfig.splash to expo-splash-screen plugin
- add expo-status-bar and expo-splash-screen to plugins list
- fix AnimatedStyleHandle<ViewStyle> type error in conversations.tsx (Reanimated 4)
- remove unstable_enablePackageExports from metro config (default since SDK 53)
- remove @babel/core from devDependencies (implicit package managed by Expo)
- update expo-sqlite override in root package.json: ~55 → ~56
- exclude typescript from expo version check (TS 6 upgrade is a separate effort)
|
Warning Review limit reached
More reviews will be available in 13 minutes and 56 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (2)
WalkthroughUpgrades Expo SDK from ~55.x to ~56.x across all package manifests, migrates React Navigation imports ( ChangesExpo SDK 56 Upgrade
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Coverage Report for packages/overpass (./packages/overpass)
File CoverageNo changed files found. |
Coverage Report for apps/expo (./apps/expo)
File CoverageNo changed files found. |
Coverage Report for packages/analytics (./packages/analytics)
File CoverageNo changed files found. |
Coverage Report for packages/units (./packages/units)
File CoverageNo changed files found. |
Coverage Report for packages/mcp (./packages/mcp)
File CoverageNo changed files found. |
Coverage Report for packages/api (./packages/api)
File CoverageNo changed files found. |
Bumps the nativewindui package across all three consumers (root override, packages/ui, apps/expo) from 2.0.6 → 2.2.0.
React Native 0.85.3 bundles react-native-renderer@19.2.3. The previous override of react@19.2.6 caused an "Incompatible React versions" crash on startup.
Fixes Android crash — "Couldn't find a route object" — caused by LargeTitleHeader importing useRoute from @react-navigation/native, which reads from a different NavigationRouteContext than the one expo-router SDK 56 populates. The fix is shipped in 2.2.1, so the 2.2.0 patch is no longer needed and is removed.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/expo/app.config.ts`:
- Around line 80-82: The `expo-navigation-bar` plugin is missing from the
plugins array in the app config. Add a new entry to the plugins array (alongside
the other plugins like `@sentry/react-native`, `expo-status-bar`, and
`expo-splash-screen`) that includes the `expo-navigation-bar` plugin configured
with `enforceContrast: false` as an object parameter. This configuration is
required for the `NavigationBar.setStyle()` calls in `useColorScheme.tsx` to
work properly; without it, the OS will override manual style changes and the
Android theme-sync will not function.
In `@apps/expo/lib/hooks/useColorScheme.tsx`:
- Around line 13-17: The catch block for the setNavigationBar call in
useColorScheme.tsx only logs errors to console and does not report them to
Sentry for production telemetry tracking. Import captureException from
`@sentry/react-native` at the top of the file, then in the catch block, call
Sentry.captureException(error) before or after the console.error call to ensure
the error is captured in production telemetry while preserving the original
error object and logging behavior. This aligns with the coding guidelines
requiring Sentry capture in all catch blocks for files under apps/expo.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 0638f44d-d133-486a-92f2-90c123e11fb2
⛔ Files ignored due to path filters (1)
bun.lockis excluded by!**/*.lock,!bun.lock
📒 Files selected for processing (13)
apps/expo/app.config.tsapps/expo/app/(app)/(tabs)/(home)/index.tsxapps/expo/app/(app)/demo/index.tsxapps/expo/app/(app)/messages/conversations.tsxapps/expo/app/_layout.tsxapps/expo/app/_layout.web.tsxapps/expo/app/auth/one-time-password.tsxapps/expo/lib/hooks/useColorScheme.tsxapps/expo/metro.config.jsapps/expo/package.jsonapps/expo/theme/index.tspackage.jsonpackages/ui/package.json
💤 Files with no reviewable changes (1)
- apps/expo/metro.config.js
| '@sentry/react-native', | ||
| 'expo-status-bar', | ||
| ['expo-splash-screen', { image: './assets/splash.png' }], |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# Find and inspect useColorScheme.tsx to confirm NavigationBar.setStyle usage
find apps/expo -name "useColorScheme.tsx" -type fRepository: PackRat-AI/PackRat
Length of output: 101
🏁 Script executed:
# Check the full app.config.ts to see complete plugin list and verify expo-navigation-bar absence
cat -n apps/expo/app.config.ts | head -100Repository: PackRat-AI/PackRat
Length of output: 3613
🏁 Script executed:
# Search for NavigationBar references in the codebase
rg "NavigationBar" apps/expo/ -A 3 -B 2Repository: PackRat-AI/PackRat
Length of output: 1930
🌐 Web query:
expo-navigation-bar enforceContrast plugin configuration setStyle
💡 Result:
In the expo-navigation-bar plugin, the enforceContrast configuration option determines whether the operating system maintains a translucent navigation bar to ensure contrast between navigation buttons and your app content [1][2][3]. Plugin Configuration: You can configure this in your app.json (or app.config.js/ts) file within the plugins array. Setting enforceContrast to true (the default) enables this behavior [1][2][3]: { "expo": { "plugins": [ [ "expo-navigation-bar", { "enforceContrast": true, "barStyle": "light", "visibility": "visible" } ] ] } } Important Note on setStyle: The NavigationBar.setStyle(style) and NavigationBar.setButtonStyleAsync(style) functions are designed to control the color of navigation bar buttons (e.g., light or dark) [1][2][3]. However, these functions will only have an effect if the following conditions are met: 1. The enforceContrast option is set to false [1][2][3]. 2. The device is using the traditional three-button navigation bar (this does not work with gesture navigation) [1][2][4]. If enforceContrast remains true (the default), the operating system overrides manual style settings to ensure visibility, rendering setStyle calls ineffective [1][2]. Additionally, please note that there is a known bug in some Android emulator versions (notably Android 15) that may prevent these functions from working even when conditions are met [1][5][3].
Citations:
- 1: https://docs.expo.dev/versions/v55.0.0/sdk/navigation-bar/
- 2: https://docs.expo.dev/versions/latest/sdk/navigation-bar/
- 3: https://docs.expo.dev/versions/v56.0.0/sdk/navigation-bar/
- 4: https://docs.expo.dev/versions/v53.0.0/sdk/navigation-bar
- 5: https://docs.expo.dev/versions/unversioned/sdk/navigation-bar/
Add the expo-navigation-bar plugin with enforceContrast: false—otherwise NavigationBar.setStyle() calls will be silently ignored.
The new setStyle() calls in useColorScheme.tsx depend on the expo-navigation-bar plugin configured with enforceContrast: false. Without this config, the OS overrides manual style changes, making the Android theme-sync a no-op. (Note: this also only works on traditional three-button navigation, not gesture navigation.)
Suggested fix
'`@react-native-community/datetimepicker`',
'`@sentry/react-native`',
+ ['expo-navigation-bar', { enforceContrast: false }],
'expo-status-bar',
['expo-splash-screen', { image: './assets/splash.png' }],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| '@sentry/react-native', | |
| 'expo-status-bar', | |
| ['expo-splash-screen', { image: './assets/splash.png' }], | |
| '`@sentry/react-native`', | |
| ['expo-navigation-bar', { enforceContrast: false }], | |
| 'expo-status-bar', | |
| ['expo-splash-screen', { image: './assets/splash.png' }], |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/expo/app.config.ts` around lines 80 - 82, The `expo-navigation-bar`
plugin is missing from the plugins array in the app config. Add a new entry to
the plugins array (alongside the other plugins like `@sentry/react-native`,
`expo-status-bar`, and `expo-splash-screen`) that includes the
`expo-navigation-bar` plugin configured with `enforceContrast: false` as an
object parameter. This configuration is required for the
`NavigationBar.setStyle()` calls in `useColorScheme.tsx` to work properly;
without it, the OS will override manual style changes and the Android theme-sync
will not function.
| try { | ||
| await setNavigationBar(colorScheme); | ||
| setNavigationBar(colorScheme); | ||
| } catch (error) { | ||
| console.error('useColorScheme.tsx", "setColorScheme', error); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check if the file exists and examine its structure
fd -t f "useColorScheme.tsx" apps/expo/Repository: PackRat-AI/PackRat
Length of output: 101
🏁 Script executed:
# Once we have the file path, let's examine the actual content
cat -n apps/expo/lib/hooks/useColorScheme.tsxRepository: PackRat-AI/PackRat
Length of output: 1986
🏁 Script executed:
# Let's also verify the Sentry import guideline applies by checking current imports in the file
head -20 apps/expo/lib/hooks/useColorScheme.tsxRepository: PackRat-AI/PackRat
Length of output: 768
Capture these native failures with Sentry instead of only logging them.
Both catch blocks only call console.error, so Android navigation-bar sync failures during theme toggles disappear from production telemetry. These errors should be reported with @sentry/react-native while preserving the original error object.
Suggested fix
+import * as Sentry from '`@sentry/react-native`';
import { COLORS } from 'expo-app/theme/colors';
import * as NavigationBar from 'expo-navigation-bar';
import { useColorScheme as useNativewindColorScheme } from 'nativewind';
import * as React from 'react';
import { Platform } from 'react-native';
@@
try {
setNavigationBar(colorScheme);
} catch (error) {
+ Sentry.captureException(error);
console.error('useColorScheme.tsx", "setColorScheme', error);
}
@@
try {
NavigationBar.setStyle(colorScheme === 'dark' ? 'light' : 'dark');
} catch (error) {
+ Sentry.captureException(error);
console.error('useColorScheme.tsx', 'setNavigationBar', error);
}
}Coding guidelines require Sentry capture in all catch blocks for files under apps/expo/**/*.{ts,tsx}.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/expo/lib/hooks/useColorScheme.tsx` around lines 13 - 17, The catch block
for the setNavigationBar call in useColorScheme.tsx only logs errors to console
and does not report them to Sentry for production telemetry tracking. Import
captureException from `@sentry/react-native` at the top of the file, then in the
catch block, call Sentry.captureException(error) before or after the
console.error call to ensure the error is captured in production telemetry while
preserving the original error object and logging behavior. This aligns with the
coding guidelines requiring Sentry capture in all catch blocks for files under
apps/expo.
Source: Coding guidelines
Physical devices can reach localhost directly; only the Android emulator needs the 10.0.2.2 alias. Guard the rewrite with !Device.isDevice.
getByText(/Add \d+ item/i) matched two elements; adding .first() satisfies Playwright's strict mode.
Summary
Breaking changes addressed
`@react-navigation/*` → `expo-router` entry points (SDK 56 requirement)
Ran the official codemod (`expo-codemod sdk-56-expo-router-react-navigation-replace`) across all source files. 6 files updated:
Removed direct `@react-navigation/{native,elements,bottom-tabs,drawer}` deps (now transitive via `expo-router`).
`expo-navigation-bar` API removed imperative setters
`setButtonStyleAsync`, `setPositionAsync`, `setBackgroundColorAsync` are gone. Updated `useColorScheme.tsx` to use the new synchronous `NavigationBar.setStyle()`.
`ExpoConfig.splash` removed from top-level type
Migrated `splash: { image }` from the deprecated top-level `ExpoConfig` field to the `expo-splash-screen` plugin config.
Reanimated 4 `AnimatedStyleHandle` type change
Updated `checkboxContainerStyle` prop type in `conversations.tsx` from `ViewStyle` to `AnimatedStyle`.
Housekeeping
Test plan
Summary by CodeRabbit
Chores
Bug Fixes