Migration9 min read

Upgrading from Capacitor 7 to Capacitor 8

A step-by-step guide to upgrading a project from Capacitor 7 to Capacitor 8 — dependency bumps, native project changes, breaking changes to watch, and keeping your OTA runtime version in sync.

Major Capacitor upgrades are usually smoother than the version number suggests — the team is conservative about breaking changes — but “usually” isn't “always,” and the failures cluster in predictable places. This guide walks through upgrading a project from Capacitor 7 to 8, what to watch for, and how to keep your OTA runtime version in sync.

Do this on a branch, and treat it as a native release. A major Capacitor bump changes the native projects, so it ships in a new store binary — not over the air.

1. Bump the packages together

npm install @capacitor/core@8 @capacitor/cli@8 \
  @capacitor/ios@8 @capacitor/android@8
npx cap sync

Keep them on the same major — a mixed 7/8 install is the fastest way to a mismatch error. See fixing version mismatch.

2. Update the plugins

Update every @capacitor/* plugin to its version 8 release, and check community plugins for Capacitor 8 compatibility. A plugin with no v8-compatible release is your blocker — resolve it before going further.

3. Handle the breaking changes

Read the official 7→8 migration guide and apply its codemod/steps. Breaking changes typically touch minimum OS versions, a few renamed APIs, and native project settings. The upgrade tooling handles most of the mechanical edits; the manual part is your own code that used a changed API.

4. Raise the native floors if required

A new major often raises minimum iOS/Android versions and SDK levels. Update your deployment targets and compileSdk accordingly — this can interact with the Xcode requirement and AGP 9.

5. Bump your OTA runtime version

Here's the OTA-specific step teams forget: the new binary is a new native runtime. Increment your OtaKit runtime version so bundles built for Capacitor 8 only reach the upgraded shells, and older shells keep getting compatible bundles until users update. See semantic versioning for bundles.

Test the full loop on a real device before submitting: fresh install of the new binary, then an OTA update on top of it. That confirms both the native upgrade and the runtime-version boundary in one pass.

Where to go next

See Channels & runtime version for the compatibility boundary and testing OTA updates for the verification pass.

Related docs