Skip to content

Finish the Expo SDK migration for clients/react-native: RN 0.76.5 → ~0.82 and expo-av → expo-audio/expo-video (currently held back at SDK 52) #1584

Closed

Description

@rbuergi

The npm-major bump in 688ce589b (PR #1555) moved expo 52 → 57 and react 18 → 19 in clients/react-native but left react-native pinned at 0.76.5. That combination is not resolvable, so both RN jobs in the Clients workflow fail at npm ci and have been red since 12:05Z on 2026-08-14:

  • RN connector (typecheck + test)
  • RN web (Playwright)
npm error ERESOLVE could not resolve
npm error Found: @types/react@19.2.18
npm error Could not resolve dependency:
npm error peerOptional @types/react@"^18.2.6" from react-native@0.76.5

react-native@0.76.5 declares peerDependencies: { react: "^18.2.0", "@types/react": "^18.2.6" } — the react one is a hard peer. RN 0.76 predates React 19 support entirely (RN 0.78 was the first React 19 release).

#1583 fixed the other four red client jobs (TypeScript 7 migration) and deliberately left this one alone, because every small fix is either unprovable or breaks something else.

Why the cheap fixes don't work

candidate why not
npm ci --legacy-peer-deps / an overrides entry for @types/react Forces an install of a combination upstream does not support. RN web is a Playwright job that actually exports and renders the app — "it installed" is not evidence it works, and RN 0.76.5 + React 19 cannot be shown to work because it isn't supported.
Pin @types/react back to ~18 for the RN package only Tested — fails. RN typechecks the source-aliased renderer (../react/src), which resolves its React types from clients/react/node_modules/@types/react (v19), while RN's own files use v18. Two React type identities in one program → TS2786: 'RenderArea' cannot be used as a JSX component … Type 'bigint' is not assignable to type 'ReactNode' at every JSX call site.
Revert clients/react to React 18 too Would re-break Portal-next, which is green on React 19 after #1567.

The coherent direction is forward

react-native@0.82 declares peers react: ^19.1.1 / @types/react: ^19.1.1 — exactly what the tree already has. So the fix is to finish the upgrade dependabot half-started:

  • react-native 0.76.5 → the version Expo SDK 57 expects (~0.82) — six RN minors, including the New Architecture default.
  • Reconcile expo-av. It is deprecated and removed from recent Expo SDKs; clients/react-native uses it for the speech / push-to-talk pipeline that npx vitest run covers, so this needs porting to expo-audio / expo-video, not just a version bump.
  • Re-run the Playwright web export end to end.

The repo already anticipated this — clients/react-native/package.json carries the note:

the real fix is the Expo SDK upgrade (expo@57 + react-native@0.86), which is its own migration.

Blast radius while this is open

Contained. main-cd.yml triggers on MeshWeaver Build and Test (not Clients), and its image legs build grpc-web + portal-next only — never react-native — so these two red jobs do not strand image publication the way #1568 describes. Clients is also not a required check, so they do not block merges. The cost is that the RN connector is unverified until this lands.

Related: #1568 (a red Clients is only advisory), #1583 (the other four jobs).

Activity

  1. rbuergi commented on Aug 14, 2026

    @rbuergi
    ContributorAuthor

    Update: the single-React-identity hypothesis was tested. It works — for one of the two halves.

    The failure here is two independent defects, and separating them changes what this issue is for. #1587 takes both RN jobs green; this issue narrows to the Expo/RN upgrade itself.

    The typecheck half was a RESOLUTION problem, not a version problem

    Hypothesis tested: the 28 × TS2786 come from RN's program carrying two @types/react identities — its own, plus the one under clients/react/node_modules reached through the ../react/src source alias — rather than from any real React 18/19 incompatibility. The tsc equivalent of the bundler dedupe portal-next already does with webpack resolve.modules.

    Confirmed. paths entries pinning react / react/jsx-runtime / react-dom to one copy take the typecheck from 28 errors → 0.

    The control that makes this a fix rather than a workaround: pinning to the other copy (@types/react 19) also gives 0 errors. So the shared renderer core compiles cleanly against either major — the collision was purely about there being two, never about which. Nothing is being suppressed or papered over.

    Worth keeping in mind for the upgrade itself: this dedupe is needed regardless of which React version RN lands on. It is a property of sharing source across two packages with their own node_modules, not of the version skew.

    The install half is a genuine version incompatibility — npm is telling the truth

    This one does not dissolve. react-native@0.76.5 hard-peers react: ^18.2.0:

    Found: react@19.2.8
    Could not resolve dependency: peer react@"^18.2.0" from react-native@0.76.5
    

    Note the CI log surfaced the peerOptional @types/react conflict, which is not the binding one — pinning @types/react back to 18 leaves the error unchanged. So the incidental-vs-real question resolves as: real.

    Not taken, deliberately: --legacy-peer-deps, --force, an overrides entry. Each installs a combination upstream does not support, and RN web is a Playwright job that actually renders — an install succeeding is not evidence it works.

    What #1587 does, and what is left here

    #1587 holds only the React/Expo half at the last coherent versions (expo 52 / react 18.3.1) and keeps dependabot's typescript 7 bump, with the dedupe above. Both RN jobs go green: npm ci ok, tsc --noEmit 0 errors, vitest 16 files / 156 tests, and RN web observed green on CI.

    This issue stays open for the real upgrade, now without a red workflow attached to it:

    • react-native 0.76.5 → the version Expo SDK 57 expects (~0.82; its peers are exactly react: ^19.1.1 / @types/react: ^19.1.1, which is what the rest of the tree already has).
    • Port expo-av — deprecated and removed from recent Expo SDKs, and used here by the speech / push-to-talk pipeline that vitest covers. This is the substantive part, not the version bump.
    • Re-run the Playwright web export end to end.

    The constraint is recorded where the next sweep will hit it: _react19_note in clients/react-native/package.json, and inline in tsconfig.json.

  2. rbuergi commented on Aug 14, 2026

    @rbuergi
    ContributorAuthor

    Both jobs are green on main and have been since a1ed1eb34. Verified rather than assumed — the latest three Clients runs on main (31834449450, 31829541352, 31818602224) are success, and on the newest one every job passes including RN connector (typecheck + test) and RN web (Playwright).

    The resolution was the third option this issue did not list: hold the sweep back rather than force it through or finish it. clients/react-native/package.json on main is expo ~52.0.0, react 18.3.1, react-native 0.76.5, @types/react ~18.3.0 — the combination upstream actually supports — and that commit records two further defects found on CI rather than by inference, notably that TypeScript 7 breaks expo export outright (@expo/cli SDK 52 reads tsconfig through the classic TS compiler API, which TS 7 deleted).

    So the reported symptom is gone, and the analysis in this issue stands: the cheap fixes are still wrong for the reasons given (--legacy-peer-deps and an overrides entry both force an unsupported combination past a Playwright job that actually renders, and pinning @types/react back to 18 splits the React type identity against the source-aliased renderer).

    What is left is the forward migration, which is a piece of work rather than a red build:

    • react-native 0.76.5 → ~0.82 (six minors, New Architecture default) with Expo SDK 57;
    • port expo-av → expo-audio / expo-video — it is deprecated and removed from recent SDKs, and it backs the speech / push-to-talk pipeline vitest covers, so this is a port, not a bump;
    • re-run the Playwright web export end to end.

    Retitling to that, since "the jobs are red" is no longer true and leaving it would send someone to debug a build that passes.

  3. changed the title [-]RN connector + RN web are red: dependabot bumped expo 52→57 and react 18→19 but pinned react-native at 0.76.5 (needs the Expo SDK migration)[/-] [+]Finish the Expo SDK migration for clients/react-native: RN 0.76.5 → ~0.82 and expo-av → expo-audio/expo-video (currently held back at SDK 52)[/+] on Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions