Expo upgrade skill

Guidelines for upgrading Expo SDK versions and fixing dependency issues

by expo·MIT license·★ 2,657 Stars on the repo·GitHub ↗

Use now

Files of Expo upgrade

expo/main1 file shown
SKILL.md
Show the full text151 lines

References

  • ./references/react-19.md -- SDK +54: React 19 changes (useContext → use, Context.Provider → Context, forwardRef removal)
  • ./references/new-architecture.md -- SDK +53: New Architecture migration guide
  • ./references/react-compiler.md -- SDK +54: React Compiler setup and migration guide
  • ./references/native-tabs.md -- SDK +55: Native tabs changes (Icon/Label/Badge now accessed via NativeTabs.Trigger.*)
  • ./references/expo-av-to-audio.md -- SDK +55: Migrate audio playback and recording from expo-av to expo-audio
  • ./references/expo-av-to-video.md -- SDK +55: Migrate video playback from expo-av to expo-video
  • ./references/react-navigation-to-expo-router.md -- SDK +56: Migrate @react-navigation/* imports to expo-router entry points (codemod + manual mapping)

Beta/Preview Releases

Beta versions use .preview suffix (e.g., 55.0.0-preview.2), published under @next tag.

Check if latest is beta: https://exp.host/--/api/v2/versions (look for -preview in expoVersion)

npx expo install expo@next --fix  # install beta

Step-by-Step Upgrade Process

If upgrading from SDK 55 or earlier, skip SDK 56 and upgrade directly to SDK 57. Don't use [email protected] or below. SDK 55 with Hermes V1 enabled, SDK 56, and older SDK 57 releases contain a Hermes V1 memory regression that can drastically increase memory usage when using react-native-worklets or react-native-reanimated.

  1. Upgrade Expo and dependencies
npx expo install expo@latest
npx expo install --fix
  1. Run diagnostics: npx expo-doctor

  2. Clear caches and reinstall

npx expo export -p ios --clear
rm -rf node_modules .expo
watchman watch-del-all

Breaking Changes Checklist

  • Check for removed APIs in release notes
  • Update import paths for moved modules
  • Review native module changes requiring prebuild
  • Test all camera, audio, and video features
  • Verify navigation still works correctly

Prebuild for Native Changes

First check if ios/ and android/ directories exist in the project. If neither directory exists, the project uses Continuous Native Generation (CNG) and native projects are regenerated at build time — skip this section and "Clear caches for bare workflow" entirely.

If upgrading requires native changes:

npx expo prebuild --clean

This regenerates the ios and android directories. Ensure the project is not a bare workflow app before running this command.

Clear caches for bare workflow

These steps only apply when ios/ and/or android/ directories exist in the project:

  • Clear the cocoapods cache for iOS: cd ios && pod install --repo-update
  • Clear derived data for Xcode: npx expo run:ios --no-build-cache
  • Clear the Gradle cache for Android: cd android && ./gradlew clean

Housekeeping

  • Review release notes for the target SDK version at https://expo.dev/changelog
  • Update versioned docs links in agent instruction files (AGENTS.md). The default template links to https://docs.expo.dev/versions/v<version>/. Search for docs.expo.dev/versions/ and bump each link to the new SDK version.
  • If using Expo SDK 54 or later, ensure react-native-worklets is installed — this is required for react-native-reanimated to work.
  • Enable React Compiler in SDK 54+ by adding "experiments": { "reactCompiler": true } to app.json — it's stable and recommended
  • Delete sdkVersion from app.json to let Expo manage it automatically
  • Review formerly implicit packages such as @babel/core, babel-preset-expo, and expo-constants individually instead of removing them wholesale. Keep any package that an installed dependency declares as a required peer.
  • Keep expo-constants as a direct dependency whenever expo-router is installed. Expo Router imports it and declares it as a required peer; relying on a transitive copy can break native autolinking outside Expo Go.
  • After removing any dependency, immediately run npx expo-doctor and restore anything it reports as a missing required peer.
  • If the babel.config.js only contains 'babel-preset-expo', delete the file
  • If the metro.config.js only contains expo defaults, delete the file

Deprecated Packages

Old Package Replacement
expo-av expo-audio and expo-video
expo-permissions Individual package permission APIs
@expo/vector-icons expo-symbols (for SF Symbols)
AsyncStorage expo-sqlite/localStorage/install
expo-app-loading expo-splash-screen
expo-linear-gradient experimental_backgroundImage + CSS gradients in View

When migrating deprecated packages, update all code usage before removing the old package. For expo-av, consult the migration references to convert Audio.Sound to useAudioPlayer, Audio.Recording to useAudioRecorder, and Video components to VideoView with useVideoPlayer.

expo.install.exclude

Check if package.json has excluded packages:

{
  "expo": { "install": { "exclude": ["react-native-reanimated"] } }
}

Exclusions are often workarounds that may no longer be needed after upgrading. Review each one.

Removing patches

Check if there are any outdated patches in the patches/ directory. Remove them if they are no longer needed.

Postcss

  • autoprefixer isn't needed in SDK +53. Remove it from dependencies and check postcss.config.js or postcss.config.mjs to remove it from the plugins list.
  • Use postcss.config.mjs in SDK +53.

Metro

Remove redundant metro config options:

  • resolver.unstable_enablePackageExports is enabled by default in SDK +53.
  • experimentalImportSupport is enabled by default in SDK +54.
  • EXPO_USE_FAST_RESOLVER=1 is removed in SDK +54.
  • cjs and mjs extensions are supported by default in SDK +50.
  • Expo webpack is deprecated, migrate to Expo Router and Metro web.

Hermes engine v1

Hermes V1 is the default on SDK 56 and later. SDK 55 apps using Hermes V1, all SDK 56 apps, and SDK 57 apps before [email protected] may encounter a memory regression when importing react-native-worklets or react-native-reanimated. Upgrade directly to SDK 57 and [email protected] or later. Do not recommend Worklets Bundle Mode as a production workaround; it is unsupported and experimental and may not work as expected.

Do not guide users to opt in to or out of Hermes V1. Changing the Hermes version from the SDK default is unsupported and has significant build and dependency-management caveats.

New Architecture

The new architecture is enabled by default, the app.json field "newArchEnabled": true is no longer needed as it's the default. Expo Go only supports the new architecture as of SDK +53.

Submitting Feedback

If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:

npx --yes submit-expo-feedback@latest --category skills --subject "expo-upgrade" "<actionable feedback>"

Only submit when you have something specific and actionable to report. Include as much relevant context as possible. If an AI agent repeatedly failed or the user had to take over an Expo task, load the expo-skill-feedback skill and follow its eval-candidate flow instead of reusing the command above.

1---
2name: expo-upgrade
3description: Guidelines for upgrading Expo SDK versions and fixing dependency issues
4version: 1.0.0
5license: MIT
6---
7 
8## References
9 
10- ./references/react-19.md -- SDK +54: React 19 changes (useContext → use, Context.Provider → Context, forwardRef removal)
11- ./references/new-architecture.md -- SDK +53: New Architecture migration guide
12- ./references/react-compiler.md -- SDK +54: React Compiler setup and migration guide
13- ./references/native-tabs.md -- SDK +55: Native tabs changes (Icon/Label/Badge now accessed via NativeTabs.Trigger.\*)
14- ./references/expo-av-to-audio.md -- SDK +55: Migrate audio playback and recording from expo-av to expo-audio
15- ./references/expo-av-to-video.md -- SDK +55: Migrate video playback from expo-av to expo-video
16- ./references/react-navigation-to-expo-router.md -- SDK +56: Migrate `@react-navigation/*` imports to `expo-router` entry points (codemod + manual mapping)
17 
18## Beta/Preview Releases
19 
20Beta versions use `.preview` suffix (e.g., `55.0.0-preview.2`), published under `@next` tag.
21 
22Check if latest is beta: https://exp.host/--/api/v2/versions (look for `-preview` in `expoVersion`)
23 
24```bash
25npx expo install expo@next --fix # install beta
26```
27 
28## Step-by-Step Upgrade Process
29 
30> If upgrading from SDK 55 or earlier, skip SDK 56 and upgrade directly to SDK 57. Don't use `[email protected]` or below. SDK 55 with Hermes V1 enabled, SDK 56, and older SDK 57 releases contain a Hermes V1 memory regression that can drastically increase memory usage when using `react-native-worklets` or `react-native-reanimated`.
31 
321. Upgrade Expo and dependencies
33 
34```bash
35npx expo install expo@latest
36npx expo install --fix
37```
38 
392. Run diagnostics: `npx expo-doctor`
40 
413. Clear caches and reinstall
42 
43```bash
44npx expo export -p ios --clear
45rm -rf node_modules .expo
46watchman watch-del-all
47```
48 
49## Breaking Changes Checklist
50 
51- Check for removed APIs in release notes
52- Update import paths for moved modules
53- Review native module changes requiring prebuild
54- Test all camera, audio, and video features
55- Verify navigation still works correctly
56 
57## Prebuild for Native Changes
58 
59**First check if `ios/` and `android/` directories exist in the project.** If neither directory exists, the project uses Continuous Native Generation (CNG) and native projects are regenerated at build time — skip this section and "Clear caches for bare workflow" entirely.
60 
61If upgrading requires native changes:
62 
63```bash
64npx expo prebuild --clean
65```
66 
67This regenerates the `ios` and `android` directories. Ensure the project is not a bare workflow app before running this command.
68 
69## Clear caches for bare workflow
70 
71These steps only apply when `ios/` and/or `android/` directories exist in the project:
72 
73- Clear the cocoapods cache for iOS: `cd ios && pod install --repo-update`
74- Clear derived data for Xcode: `npx expo run:ios --no-build-cache`
75- Clear the Gradle cache for Android: `cd android && ./gradlew clean`
76 
77## Housekeeping
78 
79- Review release notes for the target SDK version at https://expo.dev/changelog
80- Update versioned docs links in agent instruction files (`AGENTS.md`). The default template links to `https://docs.expo.dev/versions/v<version>/`. Search for `docs.expo.dev/versions/` and bump each link to the new SDK version.
81- If using Expo SDK 54 or later, ensure react-native-worklets is installed — this is required for react-native-reanimated to work.
82- Enable React Compiler in SDK 54+ by adding `"experiments": { "reactCompiler": true }` to app.json — it's stable and recommended
83- Delete sdkVersion from `app.json` to let Expo manage it automatically
84- Review formerly implicit packages such as `@babel/core`, `babel-preset-expo`, and `expo-constants` individually instead of removing them wholesale. Keep any package that an installed dependency declares as a required peer.
85- Keep `expo-constants` as a direct dependency whenever `expo-router` is installed. Expo Router imports it and declares it as a required peer; relying on a transitive copy can break native autolinking outside Expo Go.
86- After removing any dependency, immediately run `npx expo-doctor` and restore anything it reports as a missing required peer.
87- If the babel.config.js only contains 'babel-preset-expo', delete the file
88- If the metro.config.js only contains expo defaults, delete the file
89 
90## Deprecated Packages
91 
92| Old Package | Replacement |
93| -------------------- | ---------------------------------------------------- |
94| `expo-av` | `expo-audio` and `expo-video` |
95| `expo-permissions` | Individual package permission APIs |
96| `@expo/vector-icons` | `expo-symbols` (for SF Symbols) |
97| `AsyncStorage` | `expo-sqlite/localStorage/install` |
98| `expo-app-loading` | `expo-splash-screen` |
99| expo-linear-gradient | experimental_backgroundImage + CSS gradients in View |
100 
101When migrating deprecated packages, update all code usage before removing the old package. For expo-av, consult the migration references to convert Audio.Sound to useAudioPlayer, Audio.Recording to useAudioRecorder, and Video components to VideoView with useVideoPlayer.
102 
103## expo.install.exclude
104 
105Check if package.json has excluded packages:
106 
107```json
108{
109 "expo": { "install": { "exclude": ["react-native-reanimated"] } }
110}
111```
112 
113Exclusions are often workarounds that may no longer be needed after upgrading. Review each one.
114 
115## Removing patches
116 
117Check if there are any outdated patches in the `patches/` directory. Remove them if they are no longer needed.
118 
119## Postcss
120 
121- `autoprefixer` isn't needed in SDK +53. Remove it from dependencies and check `postcss.config.js` or `postcss.config.mjs` to remove it from the plugins list.
122- Use `postcss.config.mjs` in SDK +53.
123 
124## Metro
125 
126Remove redundant metro config options:
127 
128- resolver.unstable_enablePackageExports is enabled by default in SDK +53.
129- `experimentalImportSupport` is enabled by default in SDK +54.
130- `EXPO_USE_FAST_RESOLVER=1` is removed in SDK +54.
131- cjs and mjs extensions are supported by default in SDK +50.
132- Expo webpack is deprecated, migrate to [Expo Router and Metro web](https://docs.expo.dev/router/migrate/from-expo-webpack/).
133 
134## Hermes engine v1
135 
136Hermes V1 is the default on SDK 56 and later. SDK 55 apps using Hermes V1, all SDK 56 apps, and SDK 57 apps before `[email protected]` may encounter a memory regression when importing `react-native-worklets` or `react-native-reanimated`. Upgrade directly to SDK 57 and `[email protected]` or later. Do not recommend Worklets Bundle Mode as a production workaround; it is unsupported and experimental and may not work as expected.
137 
138Do not guide users to opt in to or out of Hermes V1. Changing the Hermes version from the SDK default is unsupported and has significant build and dependency-management caveats.
139 
140## New Architecture
141 
142The new architecture is enabled by default, the app.json field `"newArchEnabled": true` is no longer needed as it's the default. Expo Go only supports the new architecture as of SDK +53.
143 
144## Submitting Feedback
145If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
146```bash
147npx --yes submit-expo-feedback@latest --category skills --subject "expo-upgrade" "<actionable feedback>"
148```
149Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
150If an AI agent repeatedly failed or the user had to take over an Expo task, load the expo-skill-feedback skill and follow its eval-candidate flow instead of reusing the command above.
151 

Discussion

Alternatives

`expo-overview` — router & shared rules for Expo / EASEntry point and router for every Expo or EAS task. Load this skill first — before writing code and before choosing another expo-* / eas-* skill — when the request, PRD, or spec mentions Expo, EAS, Expo Go, or an expo-* package, or the project has an `expo` dependency in `package.json`. Within that gate it also covers app specs and designs to implement (tabs, stacks, maps, lists, navigation, building from a screenshot), and phrasings like 'implement a mobile app', 'make my app look native', 'add navigation', 'fetch some data', 'upgrade my SDK', 'add Expo to my existing native app', 'ship to the App Store', or 'I'm new to Expo, where do I start'. A fully specified request (SDK pinned, libraries named, layout given) still routes through here — the shared setup rules still apply. Do NOT load it when neither signal is present: a bare React Native project with no `expo` dependency is not Expo work. Detects the real goal, routes to the right expo-* / eas-* skill, and owns the shared setup rules.Coding · MITAdd an App Clip to an Expo AppAdd an iOS App Clip target to an Expo app. Use when the user mentions App Clip, AASA, apple-app-site-association, appclips, smart app banner, or wants to ship a lightweight iOS Clip invoked from a URL alongside their parent app.Coding · MITApp Store DeploymentBuild and submit iOS and Android apps with EAS to TestFlight, the App Store, or Google Play. Supports Expo and other React Native projects, plus existing native apps. Use for eas.json setup, release pipelines, signing, app versions and build numbers, store submissions, and listing metadata. For Expo websites and API routes, use eas-hosting; for adding React Native screens to a native app, use expo-brownfield.Coding · MITDesigning with SleekUse when the user wants to design a mobile app or UI screens, when they mention their Sleek (sleek.design) projects, or when implementing Sleek designs in code (HTML, React Native, SwiftUI).Coding · MIT