Skip to content

build(deps): bump expo to 57 and react native to 0.86 - #520

Open
gkartalis wants to merge 4 commits into
mainfrom
bump-expo-57
Open

build(deps): bump expo to 57 and react native to 0.86#520
gkartalis wants to merge 4 commits into
mainfrom
bump-expo-57

Conversation

@gkartalis

@gkartalis gkartalis commented Sep 11, 2026

Copy link
Copy Markdown
Member

Bumps Expo 55.0.2657.0.21 and React Native 0.83.60.86.3, plus the aligned native modules and the Storybook 8 → 10 migration that came with it.

Split into three commits so each layer is reviewable on its own:

  1. build(deps) — all package.json + yarn.lock version changes.
  2. refactor(storybook) — the on-device Storybook v10 migration.
  3. fix — the RN 0.86 / Expo 57 incompatibilities found while getting it to run.

Notable changes

Storybook 8 → 10. The config directory moves from .storybook to .rnstorybook, the generated entrypoint becomes storybook.requires.ts instead of .js, withStorybook is now a named export (and useJs is gone), and main.js declares deviceAddons rather than addons. Story types now come from @storybook/react-native@storybook/react is dropped from the root.

Double worklets transform. Example/babel.config.js listed react-native-reanimated/plugin, but babel-preset-expo@57 already auto-adds react-native-worklets/plugin when the package is installed, and under Reanimated 4 the reanimated plugin is just a re-export of it. The transform was being applied twice, which broke worklets at runtime — the Storybook v10 bottom bar is gesture/bottom-sheet driven, so its taps silently did nothing.

Jest preset. The bare react-native preset is gone in 0.86; jest.config.js now points at @react-native/jest-preset, which is added as an explicit devDependency alongside @react-native/babel-preset.

Testing

  • yarn type-check — clean
  • yarn test --maxWorkers=2 — 14 suites, 60 tests passing

Note that commits 1 and 2 are not individually runnable; the tree is only green at the tip.

Still open

react-native-safe-area-context is at 5.7.0, but @storybook/react-native@10.6.0 pins that peer to exactly 5.8.0. It isn't causing a visible problem, but the v10 layout reads useSafeAreaInsets() for the bottom bar, so it may be worth aligning in a follow-up.

🤖 Generated with Claude Code

📦 Published PR as canary version: 24.13.0--canary.520.6694.0

✨ Test out this PR locally via:

npm install @artsy/palette-mobile@24.13.0--canary.520.6694.0
# or 
yarn add @artsy/palette-mobile@24.13.0--canary.520.6694.0

gkartalis and others added 3 commits September 11, 2026 15:23
Expo 55.0.26 -> 57.0.21 and React Native 0.83.6 -> 0.86.3, with the
aligned native module versions:

- react 19.2.0 -> 19.2.3, react-test-renderer to match
- react-native-reanimated 4.3.2 -> 4.5.1, react-native-worklets 0.8.3 -> 0.10.1
- react-native-gesture-handler 2.30.0 -> 2.32.0
- react-native-safe-area-context 5.6.x -> 5.7.0
- react-native-pager-view 7.0.1 -> 8.0.2, react-native-svg to 15.15.4
- @react-native-community/datetimepicker 8.6.0 -> 9.1.0, slider to 5.2.0
- @gorhom/bottom-sheet 5.2.8 -> 5.2.14
- babel-preset-expo 55.0.22 -> 57.0.11, @react-native/eslint-config to 0.86.3

Storybook moves from 8.x to 10.6.0: @storybook/react-native and both
ondevice addons, plus the storybook 10.6.0 devDependency the new CLI
needs. @storybook/react is dropped from the root, since story types now
come from @storybook/react-native.

Adds @react-native/babel-preset and @react-native/jest-preset, which
RN 0.86 requires as explicit dependencies.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Storybook React Native 10 renames the config directory and changes the
generated stories entrypoint, so:

- rename Example/.storybook to Example/.rnstorybook, the directory the
  v10 CLI and metro plugin now look for
- replace the generated storybook.requires.js with the TypeScript
  storybook.requires.ts that sb-rn-get-stories emits, and point
  .eslintignore / .prettierignore at the new path
- withStorybook is now a named export, and the useJs option is gone
- main.js declares deviceAddons instead of addons
- import story types from @storybook/react-native rather than
  @storybook/react, which is no longer a dependency

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- jest: the bare "react-native" preset was removed in 0.86; use
  @react-native/jest-preset directly
- babel: drop react-native-reanimated/plugin. babel-preset-expo 57
  auto-adds react-native-worklets/plugin when the package is installed,
  and in Reanimated 4 the reanimated plugin is only a re-export of it,
  so listing it applied the worklets transform twice
- app.json: remove the top-level splash config, which expo 57 no longer
  reads and warns about
- Dialog: StyleSheet.absoluteFillObject is no longer assignable to an
  Animated.View style array under the new types; use absoluteFill

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@artsyit artsyit added the Version: Minor A deploy for new features label Sep 11, 2026
@gkartalis gkartalis self-assigned this Sep 11, 2026
Reanimated copies a worklet's closure to the UI runtime, and that copy is deep.
When a worklet reads an exported binding, TypeScript's CommonJS output compiles
the read into `exports.<name>`, so the babel plugin captures the module's entire
`exports` object instead of the single value it needs.

Input.tsx exported `inputEvents` (an EventEmitter) from the same module as a
worklet that read `HORIZONTAL_PADDING`. Serializing that closure therefore walked
into the emitter, which has no copy strategy, and threw at mount:

  [Worklets] Cannot copy value of type `EventEmitter`.

The capture was always there; react-native-worklets 0.10 (Expo SDK 57 /
RN 0.86) serializes more strictly than 0.8 and exposed it.

- move inputEvents/emitInputClearEvent into their own module, re-exported from
  the Input barrel so the public API is unchanged
- read a module-local HORIZONTAL_PADDING_VALUE inside the worklet
- same treatment for STICKY_BAR_HEIGHT in StickySubHeader, whose worklet also
  captured exports (harmless today, since that module only exports numbers and
  a component, but the same latent trap)

Verified by compiling dist and inspecting the generated __closure objects: no
worklet in either file captures `exports` any more.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@artsyit

artsyit commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator
Warnings
⚠️

Changes were made to Example/package.json, but not to Example/yarn.lock.
Perhaps you need to run yarn install?

New dependencies added: @react-native/babel-preset, @react-native/jest-preset and storybook.

@react-native/babel-preset

Used in package.json
Author: Unknown Description: Babel preset for React Native applications
License: MIT Homepage: https://github.com/react/react-native#readme
Keywords: babel, preset and react-native
Updated: about 11 hours ago Created: over 3 years ago
Releases: 1167 Maintainers: 2
Direct Dependencies: @babel/core, react-refresh, @babel/plugin-transform-for-of, @babel/plugin-transform-classes, @babel/plugin-transform-runtime, @babel/plugin-transform-react-jsx, babel-plugin-syntax-hermes-parser, babel-plugin-transform-flow-enums, @babel/plugin-transform-typescript, @react-native/babel-plugin-codegen, @babel/plugin-syntax-dynamic-import, @babel/plugin-transform-regenerator, @babel/plugin-transform-block-scoping, @babel/plugin-transform-destructuring, @babel/plugin-transform-unicode-regex, @babel/plugin-syntax-optional-chaining, @babel/plugin-transform-react-jsx-self, @babel/plugin-transform-private-methods, @babel/plugin-syntax-export-default-from, @babel/plugin-transform-class-properties, @babel/plugin-transform-flow-strip-types, @babel/plugin-transform-modules-commonjs, @babel/plugin-transform-react-jsx-source, @babel/plugin-transform-optional-chaining, @babel/plugin-proposal-export-default-from, @babel/plugin-transform-async-to-generator, @babel/plugin-transform-react-display-name, @babel/plugin-transform-optional-catch-binding, @babel/plugin-syntax-nullish-coalescing-operator, @babel/plugin-transform-async-generator-functions, @babel/plugin-transform-private-property-in-object, @babel/plugin-transform-nullish-coalescing-operator, @babel/plugin-transform-named-capturing-groups-regex

@react-native/jest-preset

Used in package.json
Author: Unknown Description: Jest preset for React Native apps
License: MIT Homepage: https://github.com/react/react-native#readme
Keywords: jest, preset and react-native
Updated: about 11 hours ago Created: 7 months ago
Releases: 194 Maintainers: 2
Direct Dependencies: babel-jest, regenerator-runtime, jest-environment-node, @react-native/js-polyfills, @jest/create-cache-key-function

storybook

Used in Example/package.json
Author: Unknown Description: Storybook: Develop, document, and test UI components in isolation
License: MIT Homepage: https://storybook.js.org
Keywords: storybook, component, components, design-systems, component-testing, react, next, next.js, react-native, react-native-web, vue, angular, svelte, sveltekit and web-components
Updated: 8 days ago Created: over 10 years ago
Releases: 3027 Maintainers: 8
Direct Dependencies: ws, open, recast, semver, esbuild, oxc-parser, @vitest/spy, jsonc-parser, oxc-resolver, @vitest/expect, @storybook/icons, @storybook/global, @webcontainer/env, @testing-library/dom, use-sync-external-store, @testing-library/jest-dom, @testing-library/user-event

Generated by 🚫 dangerJS against e5f9d43

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

canary Version: Minor A deploy for new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants