Skip to content

[pull] main from expo:main#884

Merged
pull[bot] merged 19 commits into
code:mainfrom
expo:main
May 20, 2026
Merged

[pull] main from expo:main#884
pull[bot] merged 19 commits into
code:mainfrom
expo:main

Conversation

@pull

@pull pull Bot commented May 20, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

Ubax and others added 19 commits May 20, 2026 11:13
…Observe (#45635)

# Why

In order to fix `markInteractive` to work properly with expo-router and
react-navigation, we need to introduce `useObserve` hook. Additionally
it is a bit confusing that people need to add `AppMetricsRoot` to use
expo-observe.

# How

Update the docs to use latest `useObserve` and `ObserveRoot` API

# Test Plan

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

---------

Co-authored-by: Kadi Kraman <kadi@expo.io>
Co-authored-by: Aman Mittal <amandeepmittal@live.com>
Co-authored-by: Kadi Kraman <kadi@expo.dev>
# Why

When using the `expo-type-information` CLI, it first preprocesses files
and combines them into one giant file (depending on what options where
used `-t, -m, -i` the file may be different) and then it passes this
file to sourcekitten. We need a way to see what the file looks like
before passing it to sourcekitten to be able to debug the preprocessing
logic more easily.

# How
Added `other preprocess-file` command to the CLI which outputs the
preprocessed file.

# Test Plan
Tested the command manually on multiple packages (`expo-video`,
`expo-blob`) with multiple type inference options.

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…46027)

## Summary

Resolves #46014
Resolves (comment of) #45909
Follow-up to #45958

When a raw `Request` is passed, because of `whatwg-fetch` not
implementing the full spec, and us not having a custom `Request` class
replacement for it, we don't thread through the `body`. We can luckily
get to the original `body` value and pass it on.

## Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

The Convex guide still described the older manual setup flow. EAS CLI
now has `eas integrations:convex:connect`, which automates the
Expo-specific setup work for connecting Convex to an EAS project.

# How

Updated the Convex guide to center setup around `eas
integrations:convex:connect`, including the steps the command now
handles:

- installing `convex`
- creating or reusing the Convex team connection
- creating the Convex project and deployment
- writing `CONVEX_DEPLOY_KEY` and `EXPO_PUBLIC_CONVEX_URL` to
`.env.local`
- creating or updating the `EXPO_PUBLIC_CONVEX_URL` EAS environment
variable
- sending the Convex team invite when possible

Kept the remaining developer steps focused on running `npx convex dev`,
adding the Convex provider, querying data, and linking to Convex's
conceptual overview instead of their React Native quickstart.

# Test Plan

Read the diff.

# Checklist

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
)

## Summary

Stack parent of:
- #45989
- #45990

The supported use-cases for `resolveFrom` in `@expo/require-utils` is
already quite wide, but what we do support can be made even more
flexible with a few more changes.

We should check whether the resolved target path is actually a file
(using `lstatSync(target, { throwIfNoEntry: false })`) to ensure we
don't accidentally resolve a directory path.
Instead of resolving directories, we should then explicitly add `/index`
resolution support.

We can also add a small optimisation to skip checking a `node_modules`
folder if it doesn't exist and add an exception for `package.json` to
skip native Node resolution and the new `/index` case.

Further, we can escape early if the input target is a file specifier,
since we won't need to do full Node resolution in that case.

This effectively allows us to use `resolveFrom`:
- for general module resolution by passing `extensions`
- in cases where we need to protect against directories being resolved
- existence cases, like `x/package.json`, which are now more efficient

In short, this allows us to use `resolveFrom` for config file resolution
too.

## Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…ith app configs (#45989)

## Summary

- Stacked on #45983
- Is stack parent of #45990

Resolves #33987
Supersedes #43427

We should align `@expo/config-plugins` loading to `@expo/config` and
support the same formats (added: `.cjs`, `.mjs`, `.ts`, `.cts`, `.mts`).
This hugely benefits local config plugins, since they don't have to
necessarily be pre-transpiled, similar to what app configs already
support. It also aligns the config plugin support in terms of ESM
support (`type: 'module'` + `.cjs`, and `.mjs` support)

Further, this branch replaces some manual file resolution logic with
`@expo/require-utils`' `resolveFrom` function. The base branch modifies
`resolveFrom` to be a generic Node file resolution utility.

This also fixes a long-standing issue that clobbered config-plugin load
errors that could happen in the catch-case of `require` (now
`loadModuleSync`), which didn't present errors in config-plugins as
nicely as we would for app configs.

Tests were updated to reflect and check the new cases. Current support
for config-plugin support should be unchanged and the changes should be
exclusively additive.

Performance of config-plugin resolution actually improves, on average,
since the old `statSync` existence checks in a `try-catch` have been
replaced (error building on `ENOENT` was expensive)

## Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…45990)

## Summary

Stacked on #45983, #45989

Fully drops `resolve-from` in favour of `@expo/require-utils`'
`resolveFrom`.

## Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…ly (#46000)

# Why

First noticed this while testing in a physical device, the three-finger
long-press dev menu gesture on iOS only stopped responding after the
next app launch when a user disabled it from the dev launcher settings.
I would expect it to take effect immediately.

Taking a look at the code, I noticed this also affected the "show on
launch" toggle, which could still auto-open the menu after being
disabled.

Root cause: the SwiftUI dev launcher in `expo-dev-launcher` wrote
preference values straight to `UserDefaults`, bypassing the
`DevMenuPreferences` setters in `expo-dev-menu`. Those setters are where
the side effects live — installing/uninstalling
`DevMenuTouchInterceptor` for the gesture recognizer, and calling
`DevMenuManager.updateAutoLaunchObserver()` for auto-launch. The values
were persisted but the live state wasn't updated until
`DevMenuPreferences.setup()` re-read UserDefaults on next launch.

# How

Routed the SwiftUI toggles through `DevMenuManager.shared` so the
setters run immediately:

- `threeFingerLongPress` → `setTouchGestureEnabled`  
- `shakeDevice` → `setMotionGestureEnabled`  
- `showOnLaunch` → new `setShowsAtLaunch` added on `DevMenuManager`
mirroring the other accessors

Removed the now-unused `saveMenuPreference` helper from
`DevLauncherViewModel`.

# Test Plan

1. Build BareExpo and run on real iOS device.
2. Open the dev launcher → Settings.
3. Toggle Three-finger long-press off. Without restarting the app,
perform a three-finger long press on the loaded app; the developer menu
should not open. Toggle it back on and confirm the gesture works again.
4. Toggle Shake to open off and shake the device; the menu should not
open. Toggle back on and confirm shake works.
6. Kill and relaunch the app; verify the persisted values are still
correct.

---------

Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com>
…46007)

Adds an optional `textStyle` field to the `@expo/ui/swift-ui` `font`
modifier so text scales with iOS Dynamic Type. Adopting
`Font.system(_:design:)` and `Font.custom(_:size:relativeTo:)` makes the
same modifier participate in Dynamic Type, the SwiftUI-native path for
[Apple's Larger Text Accessibility Nutrition
Label](https://developer.apple.com/help/app-store-connect/manage-app-accessibility/larger-text-evaluation-criteria).

```tsx
import { Host, Text } from '@expo/ui/swift-ui';
import { font } from '@expo/ui/swift-ui/modifiers';

<Host matchContents>
  <Text modifiers={[font({ textStyle: 'largeTitle', weight: 'bold' })]}>
    Scales with Dynamic Type
  </Text>
  <Text modifiers={[font({ family: 'Helvetica', size: 17, textStyle: 'body' })]}>
    Custom font that scales relative to body
  </Text>
  <Text modifiers={[font({ size: 24 })]}>
    Fixed-size, unchanged from before
  </Text>
</Host>
```

`textStyle` accepts the 11 iOS `Font.TextStyle` cases: `largeTitle`,
`title`, `title2`, `title3`, `headline`, `subheadline`, `body`,
`callout`, `footnote`, `caption`, `caption2`.

# Test Plan

Test repro with screenshots here:
[`ramonclaudio/expo-ui-dynamic-type-font-46007-repro`](https://github.com/ramonclaudio/expo-ui-dynamic-type-font-46007-repro).
The README has a default-vs-AX5 side-by-side and a typecheck
before/after.

Smoke-tested on iPhone 17 Pro simulator (iOS 26.5, Xcode 26.5) via
`apps/native-component-list`:

- `pnpm build`, `pnpm lint --max-warnings 0`, `pnpm test` (13 suites, 70
tests), and `pnpm exec tsc --noEmit` all green in `packages/expo-ui`.
- `et generate-docs-api-data -p "expo-ui/swift-ui/modifiers"`
regenerated for both unversioned and v56.0.0. Output matches what's
committed.
- Modifiers screen renders a Dynamic Type block with three lines:
`largeTitle scales`, `body scales`, `caption scales`. Setting iOS Larger
Text to AX5 via `xcrun simctl ui booted content_size
accessibility-extra-extra-extra-large` grows all three. Adjacent
fixed-size demos (`monospacedDigit`, `textCase`) hold their size.
Restoring `large` shrinks them back without an app restart.
- Standalone repro renders all 11 text styles in section 1, three
custom-family-relativeTo variants in section 2, three fixed-size demos
in section 3, and three weights on `font({ family: 'Helvetica', size:
17, weight: X })` in section 4. The weight section visibly differs
across `regular`, `bold`, `heavy` after the patch. Pre-patch, all three
rendered regular.
- Test file covers all four `resolveFont()` branches plus the
empty-object fallback. 5 cases × 4 jest projects (Node, Web, Android,
iOS) = 20 new test runs.

# Checklist

- [x] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
  - Not applicable: no module plugin touched.
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

---------

Co-authored-by: Vojtech Novak <vonovak@gmail.com>
# Why

- Currently our universal BottomSheet example behaves weird. 


https://github.com/user-attachments/assets/3741478b-5227-43f0-9dea-6d82718e5e6e

- Fix android sheet's exit animation




<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

- Adds host position absolute, pointer events none to universal
bottomsheet, this makes adding Host optional for BottomSheet and
simplifies the API. I tested it in a different ways trying to break it,
but it seems to be working fine.
- Prevent android sheet unmount until sheet exit animation is completed.
<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

Tested universal sheet docs examples.

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
Co-authored-by: Phil Pluckthun <phil@kitten.sh>
…expo-router integration (#46019)

# Why

As agreed on the meeting, let's change the way in which metric's router
names are reported to be the pattern - `(tabs)/sessions/[id]` instead of
`/sessions/123`.

The url is still passed, but as metric param

# How

Use segments to create the pattern

# Test Plan

1. Observe-tester

<img width="1293" height="209" alt="Screenshot 2026-05-20 at 11 34 30"
src="https://github.com/user-attachments/assets/04ce12e0-1814-4a72-bc64-5c9741a795a2"
/>

<img width="633" height="818" alt="image"
src="https://github.com/user-attachments/assets/c84ad0d3-a8a0-4795-859a-985539597d62"
/>



# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
-->

- [ ] I added a `changelog.md` entry and rebuilt the package sources
according to [this short
guide](https://github.com/expo/expo/blob/main/CONTRIBUTING.md#-before-submitting)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

---------

Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators May 20, 2026
@pull pull Bot added the ⤵️ pull label May 20, 2026
@pull pull Bot merged commit 1847eb2 into code:main May 20, 2026
30 of 31 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.