Skip to content

chore: bump react-native to 0.81.6#7366

Open
janicduplessis wants to merge 30 commits intodevelopfrom
@janic/rn-0.81-bump
Open

chore: bump react-native to 0.81.6#7366
janicduplessis wants to merge 30 commits intodevelopfrom
@janic/rn-0.81-bump

Conversation

@janicduplessis
Copy link
Copy Markdown
Contributor

@janicduplessis janicduplessis commented Apr 20, 2026

What changed (plus any additional context for devs)

Upgrades React Native to 0.81.6 (from 0.79.5), React to 19.1.4 (from 19.0.0), Expo SDK to 54 (from 53), @react-native-community/cli to 20.x, and @react-native/babel-preset + metro-config to 0.81.x. Old architecture is preserved β€” newArchEnabled=false on both platforms.

Plan doc: Mobile React Native 0.81 Upgrade Plan (Notion).

Native changes

  • Android
    • buildToolsVersion, compileSdkVersion, targetSdkVersion: 35 β†’ 36
    • Gradle wrapper: 8.13 β†’ 8.14.3
    • MainApplication.kt: replace SoLoader.init(...) + new-arch load() conditional with loadReactNative(this)
    • AndroidManifest.xml: add android:usesCleartextTraffic="${usesCleartextTraffic}" (cleartext config consolidated into main manifest in the 0.81 template)
    • gradle.properties: add edgeToEdgeEnabled=false (opt-in on old Android, mandatory on API 36)
  • iOS
    • Podfile: remove :hermes_enabled and :new_arch_enabled from use_react_native! (no longer accepted by 0.81); pass :new_arch_enabled => false explicitly so it doesn't default to true
    • Info.plist (per target): add RCTNewArchEnabled=false β€” RN 0.81's RCTUtils.mm reads it from the bundle main info dictionary at runtime to decide whether to enable the new architecture

JS / config changes

  • metro.config.js: metro-config/src/defaults/exclusionList β†’ metro-config/private/defaults/exclusionList (with .default export). Drops unstable_enablePackageExports = false override (now the default).
  • src/debugging/network.js: XHRInterceptor moved from react-native/src/private/inspector/ to react-native/src/private/devsupport/devmenu/elementinspector/.
  • package.json resolution: pin axios to ^1.16.0 so the react-native export condition (added in axios 1.10) routes Metro to dist/browser/axios.cjs instead of the Node CJS that requires http/https/stream/etc. Without it, reservoir-sdk's top-level axios.create() crashes Hermes on launch with Cannot read property 'prototype' of undefined.

Patches

  • react-native+0.79.5.patch β†’ react-native+0.81.6.patch: accessibility-label nil-check was upstreamed in 0.81 and is dropped. Only the cornerCurve = kCACornerCurveContinuous fix in RCTView.m remains (targeting the old-arch ObjC path).
  • expo-linear-gradient+14.1.5.patch β†’ expo-linear-gradient+15.0.8.patch: same 1-line Display P3 color-space change, renamed for the new version (content applies cleanly).
  • @react-native-menu+menu+1.2.3.patch β†’ @react-native-menu+menu+2.0.0.patch: same Android dismiss/disabled/modal-tracking patch, renamed for the new version.
  • New: patches/@shopify+react-native-performance+4.1.2.patch adds an override-return-type fix for getExportedCustomDirectEventTypeConstants (MutableMap β†’ Map in 0.81).
  • New: patches/react-native-fs+2.16.6.patch β€” RNFSManager.unlink's Promise.reject(null, …) trips RN 0.81's @NonNull code annotation; pass "ERROR" instead.
  • Renamed/reduced: patches/react-native-animateable-text+0.16.0-beta.0.patch β†’ patches/react-native-animateable-text+0.17.1.patch. The runtime fix is upstream in 0.17.1's source but the published lib/typescript/src/*.d.ts files weren't regenerated and still carry Omit<TextProps, "children">. Patch updates the two distributed .d.ts files so TypeScript stops failing on <AnimatedText>{children}</AnimatedText>.
  • Removed: patches/react-native-reanimated+3.19.4.patch β€” the makeSynchronizable / Synchronizable additions are upstream in 3.19.5.

All six patches affected by this PR have a # PATCH CONTEXT header (per Ivan's Patch Management RFC) with Why / Upstream Issue / Linear Issue / Remove when, anchored to FEPLAT tickets:

  • react-native+0.81.6.patch β€” FEPLAT-97
  • react-native-fs+2.16.6.patch β€” FEPLAT-93 (migrate to expo-file-system; draft PR #7428)
  • @shopify+react-native-performance+4.1.2.patch β€” FEPLAT-94 (deprecated lib; replacement PoCs #7424 and #7426)
  • expo-linear-gradient+15.0.8.patch β€” FEPLAT-96
  • @react-native-menu+menu+2.0.0.patch β€” FEPLAT-95
  • react-native-animateable-text+0.17.1.patch β€” FEPLAT-98

Out of scope

  • New architecture migration.
  • react-native-reanimated is bumped to 3.19.5 (last 3.x release that still supports the old architecture; v4 is new-arch only).
  • react-native-webview already migrated to the rainbow fork in #7314, which tracks 13.16.x with RN 0.81 compatibility.
  • Expo pin deviations: react-native-svg (15.15.4) and react-native-gesture-handler (2.31.1) are already above Expo 54's pinned versions β€” no action needed.

Screen recordings / screenshots

TODO: add after running builds locally.

What to test

  • iOS: bundle exec pod install in ios/ succeeds, app builds and launches on a simulator.
  • Android: app builds (yarn android), launches, and basic navigation works (predictive back gesture is opt-in by default on API 36 via edgeToEdgeEnabled=false).
  • DApp browser loads a page (webview fork still works against 0.81 JS bridge).
  • Reanimated-driven screens animate correctly (swap sheet, bottom sheets, rainbow toast).
  • Gesture-handler interactions: scroll, drag-and-drop, button press animations.
  • Firebase messaging + remote config still init at launch (Android firebase bundle was already bumped to 23.8.8 on develop).
  • Smoke test Metro bundler: yarn start:clean and reload the app.
  • No new network logging regressions (XHRInterceptor import path moved).
  • CreateWallet flow exercises RNFSManager.unlink (the patched code path).
  • <AnimatedText>{children}</AnimatedText> type-checks (yarn lint:ci).

@socket-security
Copy link
Copy Markdown

socket-security Bot commented Apr 20, 2026

@socket-security
Copy link
Copy Markdown

socket-security Bot commented Apr 20, 2026

All alerts resolved. Learn more about Socket for GitHub.

This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored.

View full report

@janicduplessis janicduplessis marked this pull request as draft April 20, 2026 15:55
@janicduplessis janicduplessis force-pushed the @janic/rn-0.81-bump branch 2 times, most recently from de84f7f to 70bfcfe Compare April 25, 2026 15:31
@janicduplessis janicduplessis changed the title chore: bump react-native to 0.81.6 [WIP] chore: bump react-native to 0.81.6 Apr 30, 2026
@janicduplessis janicduplessis marked this pull request as ready for review April 30, 2026 19:19
@github-actions
Copy link
Copy Markdown

Launch in simulator or device for 0b557bf

@github-actions
Copy link
Copy Markdown

Launch in simulator or device for 65d6abd

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 1, 2026

Launch in simulator or device for 5bf189b

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Launch in simulator or device for da7c5ed

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Launch in simulator or device for 6fd90ee

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 2, 2026

Launch in simulator or device for 228a5f1

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Launch in simulator or device for 89d3c1f

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

πŸ§ͺ Flashlight Performance Report (AWS Device Farm)

πŸ”€ Commit: 0f2ed9d

πŸ“Ž View Artifacts

Metric Current Ξ” vs Baseline
Time to Interactive (TTI) 5418 ms 🟒 -118.7 ms (-2.1%)
Average FPS 56.40 βšͺ -0.5 (-0.9%)
Average RAM 395.8 MB βšͺ -0.9 MB (-0.2%)

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Launch in simulator or device for cd47f1e

@janicduplessis janicduplessis force-pushed the @janic/rn-0.81-bump branch from a824755 to 452bed7 Compare May 4, 2026 16:01
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 4, 2026

Launch in simulator or device for 86fbf7e

Comment thread rock.config.mjs Outdated
// Files outside native dirs that still affect the produced .app (mostly the
// JS bundle baked in via `rock bundle`). Without these, JS-only changes
// hit a stale cached .app and never make it into CI builds.
extraSources: ['is_testing', '.xcode-version', 'metro.config.js', 'metro.transform.js', 'babel.config.js'],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like an independent fix that is also "broken" on develop today and thus could be extracted to its own PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch β€” turns out it wasn't even needed in this PR. I had assumed rock's remote cache stored the final .app/.apk (with the JS bundle baked in) and that JS-only changes wouldn't bust the fingerprint, but the cache is actually only for the native build artifacts. rock bundle runs every CI run, so JS-only changes always make it into the binary regardless of fingerprint.

The "stale APK" symptom that originally motivated the addition turned out to be a silent fall-through in the metro resolver caused by a Node 22 ERR_PACKAGE_PATH_NOT_EXPORTED (fixed in 96e5f1a), unrelated to caching.

Reverted in 9443553 β€” rock.config.mjs now matches develop.

Comment thread metro.config.js
@@ -1,12 +1,15 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const blacklist = require('metro-config/src/defaults/exclusionList');
const path = require('path');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused import?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still used β€” the resolver fallback chain a few lines down references path.dirname(context.originModulePath) and path.isAbsolute(resolution). That fallback existed on develop too, but path was never imported there, so the require.resolve recovery path would have ReferenceError'd if it ever fired. This swap (dead blacklist import β†’ path) makes the existing fallback actually work.

@janicduplessis
Copy link
Copy Markdown
Contributor Author

Screen.Recording.2026-05-05.at.6.28.54.PM.mov

This is the only regression I found so far, typing on Android changes the height of the input, while previously it was stable.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Launch in simulator or device for 81ab8b9

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Launch in simulator or device for cf63a00

@janicduplessis
Copy link
Copy Markdown
Contributor Author

added workaround for that issue here 75a61e5

@olerass
Copy link
Copy Markdown
Contributor

olerass commented May 6, 2026

Pre-bumps landing separately
To keep the diff focused, two ecosystem bumps that are safe on RN 0.79 have been extracted into their own PRs and should land first:

react-native-safe-area-context 5.4.0 β†’ 5.7.0 β€” https://github.com/rainbow-me/rainbow/pull/7367
react-native-screens 4.10.0 β†’ 4.16.0 β€” https://github.com/rainbow-me/rainbow/pull/7368
This PR will rebase to drop those lines once they merge.

This can go now right?

Comment thread ios/Rainbow/Info.plist Outdated
@olerass
Copy link
Copy Markdown
Contributor

olerass commented May 6, 2026

Also desc is off here I think?

  • Desc says React 19.1.5; actual final state is 19.1.4 (after the 19.1.5 attempt was reverted in e2c8586).
  • Desc says react-native-reanimated stays on 3.19.4; actual is 3.19.5.

patch-package failed to parse the previous hunk β€” the header line
counts were off and blank context lines had no leading space, which
patch-package's parser treats as end-of-hunk.
RN 0.81 no longer exposes $REACT_NATIVE_PATH to the Xcode build env,
so the old Bundle React Native script phase broke with
"react-native-xcode.sh: No such file or directory". The sentry-xcode.sh
wrapper already invokes react-native-xcode.sh internally, so pass it
directly under with-environment.sh without the extra argument layer.
Metro's unstable_enablePackageExports now defaults to true in RN 0.81.
Zustand's ESM entry points use import.meta, which Hermes does not
support β€” causing SyntaxError 'import.meta' is currently unsupported
at store creation (createRainbowStore, createQueryStore).

Add explicit mappings under the package.json react-native field to
force Metro to resolve zustand and its subpaths to the CJS files,
bypassing the exports map.
…e export condition

With zustand@5.0.10, the package's own exports map routes the
`react-native` condition to the CJS entry (`./index.js`), so Metro no
longer resolves to the ESM files that used import.meta. The manual
subpath overrides added in 592d73b to work around v4's exports map
are no longer needed.
v1.2.3 overrode setHitSlopRect and referenced removed RN APIs; v2.0.0
drops those for RN 0.80+. Patch file renamed to match the new version
β€” contents are effectively the same minus line-number shifts.
…for RN 0.81

- flash-list: BlankAreaEvent.dispatch references eventData directly,
  but in RN 0.81's Event<T> base class eventData is protected and
  must be accessed via getEventData(). New patch file.
- react-native-performance: PerformanceMarkerManager's
  getExportedCustomDirectEventTypeConstants() overrode the base's
  MutableMap<String, Any> return type. In RN 0.81 the base changed
  to Map<String, Any> (covariant narrowing). Updated the patch to
  match.

Both hunks ported from #6924.
react-native@0.81.6 ships react-native-renderer built against
react@19.1.4. Pinning react to 19.1.5 caused a runtime crash:

  Incompatible React versions: The 'react' and 'react-native-renderer'
  packages must have the exact same version. Instead got:
  - react: 19.1.5
  - react-native-renderer: 19.1.4

Downgrading one patch matches the bundled renderer and resolves it.
The internal react-native-sandbox repo has its own RN 0.81 branch. Set
SANDBOX_BRANCH so rainbow-scripts' iOS / Android prebuild hooks check
that out instead of the default branch β€” needed until the sandbox
branch is merged. Applied to ios-e2e, android-e2e, ios-builds (both
install steps), and unit-test workflows.
…on drift

Two Android startup crashes on RN 0.81 caused by libraries reflecting on
internal RN Java fields that were renamed in 0.81's Kotlin rewrite:

- Bump react-native-animateable-text 0.16.0-beta.0 β†’ 0.17.1 to pull in RN
  0.81 + old-arch support. The pre-bump build crashed at first text view
  creation:
    java.lang.NoSuchFieldException: No field mPreparedSpannableText in
    class Lcom/facebook/react/views/text/ReactTextShadowNode;
        at com.reactnativereanimatedtext.JBTextShadowNode.<clinit>
  RN 0.81 renamed the spannable text field; v0.17.1 reads the new one.

- Bump react-native-reanimated 3.19.4 β†’ 3.19.5 (latest 3.x). Picks up
  bridge-lifecycle fixes that resolve a -Xcheck:jni abort in debug
  builds (NativeProxyCommon.requestRender called on null after JS thread
  bounces).

Verified locally with `yarn android` on Pixel 6 emulator + RN 0.81.6 +
Hermes β€” Wallet Screen renders cleanly after both bumps.

Note: the in-repo InternalModule.java reflection on
NativeModuleRegistry.mModules / ModuleHolder.mModule also needs renaming
to moduleMap / module respectively for SafeWebSocketModule to install on
RN 0.81. Filed separately since the stub committed on develop differs
from the runtime version.
RN 0.81's Metro respects package.json `exports`, routing static `import`
statements to the `.import` condition. `@reservoir0x/reservoir-sdk`
ships a Parcel-bundled `.mjs` there whose mangled named exports
(e.g. `$6496f8ee40d0c4eb$export$5d730b7aed1a3eb0 as createClient`) come
through as `undefined` once Hermes loads the release bundle.

The crash showed up on every cold launch:

    [TypeError: Cannot read property 'createClient' of undefined]
        at initializeReservoirClient

…which kills the app before the welcome screen mounts, breaking every
E2E test (iOS sim and Android emulator both β€” same JS root cause). Local
debug builds happen to work because Metro serves a different transform
in dev mode.

Override the resolver for this one package to its CJS file (`./dist/index.js`,
its `main` field). No effect on other packages.
`require.resolve('@reservoir0x/reservoir-sdk/dist/index.js')` and even
`require.resolve('@reservoir0x/reservoir-sdk/package.json')` throw
`ERR_PACKAGE_PATH_NOT_EXPORTED` on Node 22+ because the package's
`exports` field only exposes `.` (no subpath, no `./package.json`).

CI bundle step crashed in `metro.config.js` evaluation, blowing up
`Test Build` before the bundle could be produced.

Compute the path off `__dirname` instead β€” metro.config.js sits at the
workspace root, so `node_modules/@reservoir0x/reservoir-sdk/dist/index.js`
is the deterministic path. Bypasses Node's exports check entirely.
Rock's remote-build cache fingerprints native files + package.json by
default but not `metro.config.js`. Yesterday's reservoir-sdk resolveRequest
override never reached CI builds β€” rock kept serving the older cached
`.app` (fingerprint `188295d8...` β€” pre-fix) because nothing in the
fingerprint changed.

Add metro.config.js, metro.transform.js, and babel.config.js to
extraSources so JS-bundle config changes properly invalidate the cache.
RN 0.81's Metro defaults `unstable_enablePackageExports` to true, which
routes static `import` statements to packages' `import` condition. Many
npm libs ship ESM there (often Parcel-mangled, e.g. @reservoir0x/reservoir-sdk
and any transitive `class X extends Y` deps); when bundled for Hermes,
their named exports come through as `undefined` and the app crashes on
launch:

    [TypeError: Cannot read property 'prototype' of undefined]
    [TypeError: Cannot read property 'createClient' of undefined]
        at initializeReservoirClient
        at Root (App.tsx)

…which kills the app before the welcome screen mounts and breaks every
E2E + Perf test on iOS sim and Android (real device + emulator).

Disabling package exports makes Metro fall back to the `main` field
(CJS), matching what RN 0.79 effectively did and what these packages
historically test against. Replaces the per-package reservoir-sdk
override from b05b3d5 / 96e5f1a with a single config flag.
Replaces the global `unstable_enablePackageExports: false` from d50271b
(too broad β€” flips behaviour for every package) with a per-package map of
`exact moduleName β†’ CJS filepath` overrides in `metro.config.js`.

The RN 0.81 Metro / Hermes interaction crashes on launch when packages
ship Parcel-mangled ESM via the `import` condition: their named exports
come through as `undefined` in the release bundle. Reservoir-sdk was the
visible top-of-stack symptom; the underlying `prototype of undefined`
fires deeper in viem (transitively required by reservoir's CJS β€” but
viem itself shares the same export shape).

Add packages to `FORCE_CJS_PACKAGES` as we find them. If this list grows
much further, reconsider the global flag.
These three packages all ship parallel `_esm/*` and `_cjs/*` (or
`dist/esm`/`dist/cjs`) directories with mirrored `import`/`default`
conditions. Rainbow imports a handful of subpaths directly (e.g.
`viem/accounts`) and many more transitively through reservoir-sdk and
WalletConnect, so listing each subpath was unworkable.

Replace the static map with a prefix-matched override that resolves
each request to the package's `default` (CJS) export by reading the
package's `package.json` exports field directly. Bypasses Node 22's
strict subpath enforcement by joining against the package root rather
than re-resolving the subpath through `require.resolve`.

Eliminates 22 ESM module duplicates from the production Metro bundle.
Reservoir-sdk's CJS calls `axios.create()` at top-level, which fires the
moment reservoir-sdk loads. Axios's exports map gates the browser-safe
build behind a `browser` condition that Metro doesn't add on native
platforms (only on `web`), so Metro picks `dist/node/axios.cjs` β€”
which `require()`s `http`, `https`, `url`, `stream`, `zlib`, etc.

Those Node builtins resolve to undefined-or-stub in the bundle, and
their absence cascades into `Cannot read property 'prototype' of
undefined` during axios load β€” manifesting as a launch crash that
short-circuits reservoir-sdk's exports and produces the secondary
`createClient of undefined` error users see.

Pin `axios` to its browser CJS through FORCE_CJS_PACKAGES; the bundle
drops from 24 axios deps to 10 (Node builtins eliminated).
…N 0.81

`RNFSManager.reject(...)` calls `promise.reject(null, ex.getMessage())`
for the generic exception path. RN 0.81's `PromiseImpl.reject(code,
message)` is annotated `@NonNull` for `code` and trips a
`java.lang.NullPointerException: Parameter specified as non-null is
null` the moment it's invoked β€” currently fires on `unlink` during
the wallet-creation flow and crashes the app.

Pass an "ERROR" code plus the original throwable instead.
The launch crash root-caused to axios picking its Node CJS entry
(which require()s http/https/url/stream/zlib). axios 1.10.0+ added
a `react-native` export condition that maps to the browser CJS, so
forcing axios to ^1.16.0 via yarn resolutions lets Metro's normal
resolver pick the right entry.

With axios fixed, the speculative viem/ox/abitype prefix overrides
and the reservoir-sdk single-file override are no longer needed.
Strip the custom FORCE_CJS_PACKAGES map and the resolveToCjs helper
entirely; resolveRequest now just delegates to Metro and falls back
through the existing recovery chain.

axios in the production bundle is now v1.16.0 from
`dist/browser/axios.cjs`, with the Node-only deps eliminated.
The hand-rolled `diff -u` patch didn't include the `diff --git` header
that patch-package requires to locate the target file, so CI failed
postinstall with "ERROR: Failed to apply patch for package react-native-fs".

Re-emit the same one-line edit (RNFSManager.reject null code β†’ "ERROR")
in patch-package's expected format (`diff --git a/... b/...` + index +
function-context hunk header). Verified against a fresh node_modules
install of react-native-fs@2.16.6.
PR #7396 bumped @shopify/flash-list to 1.8.3, which carries the
BlankAreaEvent.kt fix our patch was applying. patch-package was
already skipping our 1.8.2-named patch because the installed
version no longer matches; remove the dead file.
… 0.81

On RN 0.81, an Android TextInput with bold weight and size 18 stops
honoring includeFontPadding:false once it has content β€” measured height
jumps from ~28px (placeholder-only) to ~40px (with text), making the
Send recipient row reflow as the user types. The placeholder path still
respects the flag, so only the populated state regresses.

Lock the input to the RN 0.79 measurement (28px β‰ˆ 18px font + ~10px
Android ascender/caret padding) so both states render identically.
The fingerprint controls only the native build cache; `rock bundle`
runs every CI build and produces a fresh JS bundle regardless.
Adding metro.config.js / metro.transform.js / babel.config.js to
extraSources doesn't keep stale bundles out of CI β€” the original
"stale APK" symptom that motivated this addition was actually a
silent fall-through in the metro resolver after a Node 22
ERR_PACKAGE_PATH_NOT_EXPORTED error, fixed in 96e5f1a.

Restore extraSources to the develop state.
iOS:
- Restore OpenInRainbow / ShareWithRainbow Info.plist to develop (last
  pod-install run reformatted these from 2-space indent to tabs; pure
  whitespace, no semantic change).
- Trim Rainbow/Info.plist back to the single RCTNewArchEnabled=false
  addition required by RN 0.81's bundle main info dictionary read in
  RCTUtils.mm. Remove four alternate-app-icon entries (baggy, chonks,
  mog, redacted) that came in via the local internals prebuild hook
  during the same pod-install dance and don't belong in this PR.

Patches:
- Drop patches/react-native-reanimated+3.19.4.patch β€” package.json now
  pins 3.19.5 which ships makeSynchronizable / Synchronizable upstream
  (verified in node_modules ReanimatedModuleProxySpec.{cpp,h}).
  Patch was already a no-op (filename version mismatch makes
  patch-package skip it).
- Drop patches/react-native-animateable-text+0.16.0-beta.0.patch β€”
  package.json now pins 0.17.1, which ships the `children`-allowed
  AnimateableTextProps shape upstream (verified in node_modules
  src/TextProps.tsx and lib/typescript/src/index.d.ts). Same no-op
  status pre-deletion.
Add `# PATCH CONTEXT` headers to the six patches affected by the RN
0.81 work, per the Patch Management RFC. Each header captures Why,
Upstream Issue, Linear Issue, and Remove when so the patch is self-
documenting and tracking is anchored to a Linear ticket.

- react-native+0.81.6.patch β€” FEPLAT-97
- react-native-fs+2.16.6.patch β€” FEPLAT-93
- @Shopify+react-native-performance+4.1.2.patch β€” FEPLAT-94
- expo-linear-gradient+15.0.8.patch β€” FEPLAT-96
- @react-native-menu+menu+2.0.0.patch β€” FEPLAT-95
- react-native-animateable-text+0.17.1.patch β€” FEPLAT-98 (new)

The animateable-text patch was deleted in d3b7aff on the
assumption that the upstream fix in 0.17.1 was complete. Source was
fixed but the published `lib/typescript/src/*.d.ts` still ship the
old `Omit<TextProps, "children">` shape, so consumers fail
TypeScript with TS2322 on `<AnimatedText>{children}</AnimatedText>`
(reproduced by `yarn lint:ci` on
src/design-system/components/Text/AnimatedText.tsx). Restore the
patch against 0.17.1's distributed types until upstream republishes.

ios/Podfile.lock: pick up animateable-text 0.16.0-beta.0 β†’ 0.17.1
(was already bumped in package.json/yarn.lock; lockfile was stale).
The previous patch only updated lib/typescript/src/TextProps.d.ts and
AnimateableText.web.d.ts, but `package.json#types` points to
lib/typescript/src/index.d.ts β€” which carries the same un-regenerated
`Omit<TextProps, "children">` shape and is what TypeScript actually
consumes when resolving the package. Local lint passed only because I
had hand-edited that file during exploration; CI hit pristine state and
TS2322 stuck.

Add the third hunk so all three published .d.ts files are aligned with
the upstream source. lint:ts now runs clean against pristine
node_modules.
@janicduplessis janicduplessis force-pushed the @janic/rn-0.81-bump branch from 9197129 to c4aee5c Compare May 6, 2026 21:04
@janicduplessis
Copy link
Copy Markdown
Contributor Author

AI was very eager to reply to you, but basically addressed all issues.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

Launch in simulator or device for 0f2ed9d

@janicduplessis janicduplessis changed the title [WIP] chore: bump react-native to 0.81.6 chore: bump react-native to 0.81.6 May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants