jimvaneijk

23g-expo-upgrade-playbook

Upgrade an Expo app to the latest stable SDK with a practical migration workflow, compatibility validation, package replacement proposals, and a final QA checklist. Use when a project needs SDK upgrades, New Architecture readiness checks, dependency compatibility checks, variant-aware config migration, or iOS/Android build stabilization.

jimvaneijk 0 Updated 2mo ago

Resources

6
GitHub

Install

npx skillscat add jimvaneijk/23g-expo-upgrade-skill

Install via the SkillsCat registry.

SKILL.md

23G Expo Upgrade Playbook

Run this workflow when upgrading an existing Expo app to the latest stable SDK and validating it end-to-end.

Skill Composition

If $upgrading-expo is available in the environment, use it as the base workflow first.

Apply this playbook on top of that baseline for:

  • project-specific exceptions,
  • variant-aware configuration migration,
  • package replacement proposals,
  • final QA checklist output contract.

If $upgrading-expo is not available, continue with this playbook only.

Required Output Contract

Always return:

  1. A short summary of what was changed.
  2. A risk list (high -> low).
  3. A concrete checklist for manual QA.
  4. Package compatibility findings and replacement proposals for problematic libs.

Workflow

1) Baseline scan

Collect and summarize:

  • Current expo, react-native, react versions.
  • Current native/deep-link/push/error-reporting libraries.
  • Whether variants exist (for example via app.variants.ts or similar config map).
  • Whether project is managed/prebuild and whether ios/ and android/ are git-tracked.
  • Whether EAS is already configured (eas.json, build profiles, env strategy).

Commands (adapt as needed):

cat package.json
rg -n "expo|react-native|react|sentry|firebase|notification|push" package.json
rg -n "variants|APP_VARIANT|bundleIdentifier|androidPackage" app.config.* app.*variants* src
test -f eas.json && cat eas.json

2) Upgrade core SDK and aligned deps

Before running commands, execute the checks from $upgrading-expo (or replicate them if unavailable), including:

  • SDK/dependency alignment,
  • diagnostics (expo-doctor),
  • breaking changes checklist,
  • deprecated package migration checks,
  • cache and prebuild hygiene.

Run:

npx expo install expo@latest
npx expo install --fix

Then resolve mismatches reported by Expo installer.

3) Config migration and structure

Prefer dynamic config in app.config.ts.

If the project already has variants, preserve that shape and avoid unnecessary redesign.

If app.variants.ts exists, keep it as source of truth.

Do not force .env loading from config unless requested.

4) iOS Firebase static-linking stabilization (known exception)

If iOS Firebase Pod errors occur with modular headers/static linking, prefer declarative Expo config via expo-build-properties plugin.

Use this pattern in app.config.ts plugin config:

  • ios.forceStaticLinking: include RNFBApp, RNFBMessaging, RNFBRCTEventEmitter.
  • ios.extraPods: include
    • FirebaseCoreInternal with modular_headers: true
    • GoogleUtilities with modular_headers: true
    • FirebaseCore with modular_headers: true
    • FirebaseInstallations with modular_headers: true

Avoid old custom Podfile patch scripts when this declarative config works.

5) Push + entitlements

If project uses RNFirebase messaging on iOS, ensure aps-environment entitlement is set (development or production per project policy).

6) Build and runtime validation

Use one of these validation paths:

Path A (fast local feedback): use prebuild to quickly test native generation and local boot.
Path B (team/release-like): use EAS builds when the team prefers not to run local prebuild.

Path A commands:

npx expo-doctor
APP_VARIANT=<variant> npx expo prebuild -p ios --clean
APP_VARIANT=<variant> npx expo prebuild -p android --clean

Path B commands (example):

npx expo-doctor
eas build --platform ios --profile <profile>
eas build --platform android --profile <profile>

Then run at least one real app boot or install test artifact per key variant.

6b) EAS detection and migration path

Always check for existing EAS setup before adding anything.

If eas.json does not exist:

If eas.json exists:

  • Preserve existing profile names and intent.
  • Migrate profiles to match current variant model and updated config keys.
  • Verify env variable mapping per profile (for example variant selection and secrets strategy).
  • Do not break existing CI assumptions unless explicitly requested.

Validation:

  • Ensure eas.json is valid JSON and profiles are usable.
  • Ensure each active variant has a mapped EAS build strategy (direct profile or documented fallback).
  • If team prefers EAS-first, prioritize EAS profile migration over local prebuild scripts.
  • Ensure all EAS setup explanation is written in English.

7) Compatibility and replacement proposals

Identify dependencies that are:

  • Unsupported/untested on New Architecture.
  • Unmaintained.
  • Breaking on current SDK.

For each problematic package, provide:

  1. Why it is risky.
  2. Recommended replacement.
  3. Migration impact (low/medium/high).
  4. Minimal migration steps.

Use references/package-replacements.md as output format.

8) Final checklist output

Generate checklist using references/qa-checklist-template.md.

Project-specific note captured from real migration

For this project, the working pattern includes:

  • Variant-driven config.
  • Firebase iOS stabilization using expo-build-properties (forceStaticLinking + extraPods modular headers).
  • Keeping current app structure if stable.

Treat that as preferred default unless the user explicitly asks to redesign.

References

  • references/qa-checklist-template.md
  • references/package-replacements.md
  • references/exceptions-template.md
  • references/runbook-template.md

Authors