Upgrading the Expo SDK is four commands, run one version at a time.
You install the new expo package, bring every other dependency into line with it, run the health check, deal with the native folders, and read the release notes for the version you landed on. Expo opens its own upgrade page with the part people skip: it recommends moving incrementally, one at a time, so that when something breaks you know which release did it. That page carries its own last-changed date of 16 October 2026 and was read here on 17 October. If you are holding a React Native and Expo project you did not type, this is the maintenance job that is genuinely yours, because nobody else can decide what your app is allowed to break. For what shipped inside a particular release, the Expo SDK release notes are the per-version read.
What follows is the documented sequence, the reason the one-at-a-time rule exists, what actually goes wrong on a project that has sat still for a year, and what changes when a builder generated the code in the first place. This is not a framework tutorial. You already have the project.
Start hereThe short version
Bump the package, align the rest, then read one set of release notes.
An Expo SDK version is a bundle. The expo package version in your package.json sets it, and that one number also pins the React Native and React versions the project is expected to run, and the native template a build starts from. That is why you never bump one line. You bump expo, then let the CLI pull everything else to the matching versions. If the relationship between the two names is new to you, what React Native is is ten minutes well spent before you start.
The one genuine fork in the road is whether the repository contains android and ios folders. Without them, the native side of an upgrade is a deletion: the next build generates fresh native projects from the new SDK template. With them, the native side is a diff you apply by hand, file by file, every time. A project handed to you by a builder almost always starts in the first state, and the moment somebody commits those folders it moves to the second one permanently.
What does Expo say the upgrade steps are?
Four steps and a read, in this order. First, install the new version of the expo package, using the version range for the SDK you are targeting rather than a bare latest. Second, run npx expo install --fix, which upgrades every other dependency to match the SDK that is now installed. Third, run npx expo-doctor to check for common problems. Fourth, update the native projects. Then read the release notes for the version you are upgrading to, including the upgrading section at the bottom of that page, which is where the per-version instructions live.
The fourth step is the one that splits. If the project uses Continuous Native Generation, Expo tells you to delete the android and ios directories when an earlier SDK version generated them locally. They come back on the next build, whether that is npx expo run:ios, npx expo prebuild or a cloud build. If the project does not use it, you run npx pod-install when there is an ios directory and apply the relevant changes from Expo's native project upgrade helper, which shows you the diff between the version you are on and the one you want. Expo's own suggestion in that case is to consider adopting prebuild so that later upgrades stop being a manual diff.
Two details are worth knowing before you type anything. The doctor check is not a formality: it reads the app config and package.json, tests dependency compatibility, and by default validates your packages against the React Native Directory, so it is the step that tells you a library has not kept up. And Expo now documents an AI agent route through the same work, its own upgrade skill, with the instruction attached that you review the proposed changes and check the changelog for version-specific steps. That is the right instruction no matter who or what typed the code. If the commands here are unfamiliar, getting started with Expo covers the toolchain they belong to.
Expo documentation, Upgrade Expo SDK, last changed 16 October 2026, read 17 October 2026
Why one version at a time, and what does skipping cost?
The reason Expo gives is diagnostic, not ceremonial. Moving one version at a time is what lets you point at the release that broke something. Jump four versions in an afternoon and you get a single event, a project that no longer builds, with four sets of breaking changes behind it and nothing to tell you which one is responsible. The commands do not get four times longer. The debugging does, and it stops being debugging and becomes guessing.
React Native's own documentation repeats the recommendation word for word, which is worth saying plainly: this is not a piece of folklore that grew in forum threads. Both first-party sources say the same thing. React Native's page adds the tool for the other case, projects that are not Expo-managed, where an Upgrade Helper gives you the full set of changes between any two versions, with comments on specific files explaining why each change is needed.
Skipping also does not save you the reading, which is the part people assume it does. Every SDK release has its own announcement carrying its own deprecations, breaking changes and anything unique to that release, so four versions means four of those. Library migration guides are worse: Expo writes its Expo Router migration guides between neighbouring SDK versions, one pair at a time. There is no guide for the combined jump, so you work through each pairwise guide in order anyway, having lost the ability to test in between. Expo even splits its changelog list in two, current versions and deprecated ones, and warns that the older posts may now carry outdated information while still being useful if you have fallen far behind. The documentation for the biggest jump is the weakest documentation Expo has.
One more cost is hidden in the engine. An SDK bump is not only new APIs: it moves what runs your JavaScript and what draws your screens, and those defaults have changed across recent releases. Read Hermes and the new architecture before you read a set of release notes, or half the entries will not mean anything to you.
What goes wrong on a project nobody has upgraded in a year?
The first thing to go is usually the easiest thing to test with. Each build of Expo Go carries one SDK version, your package.json sets the project's version, and the two have to match or the app refuses the project outright. Expo's troubleshooting page for that error, last changed 3 September 2026, states that the Apple App Store build of Expo Go stops at SDK 54 and that SDK 55 and later are not available there. On Android devices, the Android Emulator and the iOS Simulator you can still install a matching build for the version you need. Expo is blunt about the status of that app anyway: a learning environment, not a way to ship, and a development build is what a production project should be using.
On a physical iPhone that ceiling squeezes you from both sides, and it is worth knowing before you plan the upgrade rather than after. Above it, for SDK 54 and later, Expo's instruction is to build Expo Go yourself with its eas go command and hand it out through your own TestFlight internal team, which it notes requires an Apple Developer Program membership. Apple's enrolment page, read on 17 October 2026, prices that at 99 USD per membership year, and says prices may vary by region and that a fee waiver can be requested by an eligible educational institution, nonprofit or government entity. Below the ceiling, for SDK 53 or earlier, the same Expo page says you cannot install an older Expo Go on a physical iOS device at all: your options are to upgrade the project, use an Android device or the iOS Simulator, or make a development build. So if your team currently tests by handing an iPhone around with Expo Go on it, the upgrade is not only a dependency bump. It is the moment that testing habit ends, and the honest way to put it to whoever signs things off is that you are trading it for a membership or a development build either way.
The second thing is the build service. Expo says backwards compatibility for older SDK versions on its hosted services tends to be, in its words, much longer, but not forever. There is no published cutoff date, so a stale project does not get a warning letter: it gets a build that used to work and now does not. The third is the library layer, and it is the one that costs real days. Expo recommends its own install command over a plain package-manager install precisely because it picks a version compatible with your project where it can, and warns you about known incompatibilities. On a project frozen for a year, several libraries have moved past the SDK you are on and the newest versions have moved past the one you are going to.
The last cost is the one Expo names outright in its own writing on native generation: people who cannot see a safe way forward upgrade incorrectly, or start a new app and copy the old source into it. That is the real price of a year of silence, and it is not a build error. It is a team deciding the codebase is disposable. The way out is unglamorous. Upgrade one version, build it, run it, ship nothing, commit. Then do the next one.
Expo documentation, Upgrade Expo SDK and the Expo Go version mismatch page, read 17 October 2026
Check yours
What your project adds to the upgrade
Tick what is true of the project in front of you. The four commands are the same for everybody. These are the parts that are not.
Nothing ticked. Open package.json and look at the top of the file listing. If you cannot answer the first two, that is the answer: look for the folders.
The same upgrade on two different projects
Three of the five steps are identical whatever your project looks like. The native step is where the two worlds part, and so is the question of who is still holding those files in a year.
| The step | No native folders in the repo | Native folders committed | Same work |
|---|---|---|---|
| Install the target expo version | One install command, the version range for the SDK you want | One install command, the version range for the SDK you want | Same |
| Bring the other dependencies into line | expo install --fix | expo install --fix | Same |
| Run the health check | expo-doctor | expo-doctor | Same |
| Native project files | Delete android and ios, the next build regenerates them | Run pod-install, then apply the upgrade helper diffs by hand | Differs |
| Read the release notes for the version you landed on | Required, including the upgrading section at the end | Required, including the upgrading section at the end | Same |
| Who maintains the native files afterwards | The template for the SDK version you are on | You, for the life of the project | Differs |
React Native documentation, Upgrading to New Versions, read 17 October 2026
Does the upgrade work differently if a builder generated your app?
No, and that is the point worth being clear about. There is no separate upgrade path for generated code, because there is no separate kind of project. Newly writes a real React Native and Expo project you own, from a description of the app in plain English. It uploads iOS builds to TestFlight, publishes to Google Play internal testing, builds a standalone Android APK, and keeps two-way GitHub sync, so an SDK upgrade is a commit in your repository that you can read like any other. It is $25 a month, with no free tier.
Two consequences follow from owning the project rather than renting a runtime. The good one: you are not waiting for a vendor to adopt an SDK version. Nobody has to approve your upgrade, and the steps on this page are the whole procedure. The one that costs you: nobody else is going to do it either. A hosted no-code tool that upgrades its own runtime underneath you takes that work away and takes the decision with it. Here the decision is yours, which also means the calendar reminder is yours.
One asymmetry is worth planning around. Newly does not submit to the App Store for you, because Apple requires the content owner to submit an app made with a generation service. An SDK upgrade almost always ends in a new build, and sooner or later a new submission, and that submission is yours to press. Plan the upgrade for a week when you can also watch a review queue, rather than the week before a launch.
An agent can do most of this work, and Expo now documents that route itself with an upgrade skill of its own. The instruction that comes with it is the honest one: review what it proposes and check the changelog for version-specific steps. The limit has nothing to do with how good the agent is. A release note that marks a prop deprecated cannot tell you whether the screen using that prop is the one your customers open every morning. You know that. The upgrade waits for you to say so.
Questions people ask about upgrading the Expo SDK
Install the expo package version for the SDK you are targeting, run npx expo install --fix so every other dependency matches it, run npx expo-doctor, update the native projects, then read the release notes for the version you landed on. If the project has no android and ios directories, Expo says to delete any that an older SDK generated locally and let the next build regenerate them. If you maintain those directories yourself, run npx pod-install and apply the diffs from Expo's native project upgrade helper instead. Read on Expo's upgrade page, 17 October 2026.
One version, one build, one commit, then the next one
Put the next SDK bump in the calendar before you need it, do it on a branch with nothing else in flight, and keep the project in a repository you control so the diff is always readable. That is the whole discipline, and it is what keeps a year of silence from turning into a rewrite.
Start building