Skip to content

[pull] main from expo:main - #1203

Merged
pull[bot] merged 17 commits into
code:mainfrom
expo:main
Sep 1, 2026
Merged

[pull] main from expo:main#1203
pull[bot] merged 17 commits into
code:mainfrom
expo:main

Conversation

@pull

@pull pull Bot commented Sep 1, 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 : )

cornejobarraza and others added 17 commits September 1, 2026 12:18
…roperty (#49517)

# Why

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

Expo Documentation is missing an important configurable property for
`expo-location` on iOS

# How

<!--
How did you build this feature or fix this bug and why?
-->

Added missing documentation for `motionUsagePermission` on iOS

# 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).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
# Why

Remove custom conversion logic for icon following
react-navigation/react-navigation#12987

# How

<!--
How did you build this feature or fix this bug and why?
-->

# 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: Expo Bot <34669131+expo-bot@users.noreply.github.com>
# Why

Simplify pending metrics mechanism on Android and unify it with iOS

# How

1. Remove subscriber pattern and pending metrics db 
2. Change the metric/log id type to auto-incremented integer
3. Use cursor based approach
4. Save the sent cursor in `SharedPreferences`

# Test Plan

1. CI
2. Observe tester

# 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)
# Why

We are collecting crash reports locally, but we never dispatch them.

# How

Similar to JS errors dispatch crashes as logs. 

1. When crash is recorded add a new log for it
2. Trim stack trace to 50 frames, so that we don't make the log too big

The logs use following attributes:

* `event.name`: `"exception"`
* `session.id`: session associated with the crash
* `severity`: `"FATAL"`
* `exception.type`: native exception or signal name 
* `exception.message`: termination or exception reason
* `exception.stacktrace`: native call stack, when available
* `expo.error.source`: nativeCrash
* `expo.error.is_fatal`: true
* `expo.crash.signal`: signal name, such as SIGSEGV
* `expo.crash.signal_code`: numeric signal code
* `expo.crash.termination_reason`: OS-provided termination reason
* `expo.crash.exception_type`: iOS Mach exception name
* `expo.crash.exception_type_code`: iOS Mach exception type code
* `expo.crash.exception_code`: iOS processor-specific exception code
* `expo.crash.objc_exception_type`: Objective-C exception type
* `expo.crash.objc_exception_message`: Objective-C exception message

android example: 
```json
{
  "attributes": {
    "exception.message": "java.lang.ArithmeticException: divide by zero",
    "exception.stacktrace": "expo.modules.crashtester.CrashTriggers.throwFor(CrashTester.kt:76)\nexpo.modules.crashtester.CrashTriggers.trigger$lambda$0(CrashTester.kt:65)\nexpo.modules.crashtester.CrashTriggers$$ExternalSyntheticLambda0.run(D8$$SyntheticClass:0)\nandroid.os.Handler.handleCallback(Handler.java:873)\nandroid.os.Handler.dispatchMessage(Handler.java:99)\nandroid.os.Looper.loop(Looper.java:193)\nandroid.app.ActivityThread.main(ActivityThread.java:6669)\njava.lang.reflect.Method.invoke(Native Method)\ncom.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)\ncom.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)",
    "exception.type": "java.lang.ArithmeticException",
    "expo.error.is_fatal": true,
    "expo.error.source": "nativeCrash"
  },
  "body": null,
  "name": "exception",
  "severity": "fatal",
  "timestamp": "2026-08-28T12:17:47.406Z"
}
```

# Test Plan

1. CI
2. Observe-tester

# 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)
…er follow-up changes (#49557)

# Why

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

Follow-up #49515

# How

<!--
How did you build this feature or fix this bug and why?
-->

- Add missing screenshots for `cornerRadius` in the example
- Generate Expo UI and Expo Router API reference data
- Add missing changelog entry

# 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.
-->

<img width="2358" height="1142" alt="CleanShot 2026-08-31 at 21 54
18@2x"
src="https://github.com/user-attachments/assets/98849f09-414b-453a-b313-b588950e1a09"
/>


# 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)
…y join [step 1] (#49335)

# Why

**Phase 1** (PR A) of
[ENG-25370](https://linear.app/expo/issue/ENG-26085/phase-1-config-discovery-identity-join):
migrate the prebuilt-modules derivations from Ruby to autolinking
metadata.

This PR makes the TS autolinker emit a similar output as the ruby
fixture (from #49150) and contains a unit test that will verify that the
json data is the same for both outputs.

Schema decisions recorded on the ticket: a dedicated subcommand (not
`resolve` output — fingerprint isolation, and externals have no home in
`modules[]`), one document for internal + external products keyed by pod
name.

# How

Added a new `expo-modules-autolinking prebuilt-metadata --json`
subcommand emitting the following json schema:

```ts
{
  [podName]: { 
    type, 
    npmPackage, 
    packageRoot, 
    podspecDir, 
    productName 
  } 
}
``` 

This mirrors the Ruby json schema and its semantics where we get the
data from the following places:

Our e2e differential test runs the command over bare-expo and asserts
the identity fields equal the committed Ruby fixture, after the same
path canonicalization (repo-relative, pnpm store collapsed), and this
now match byte-for-byte.

The test only works in our monorepo, but that is ok since its only
consumer is the test in the monorepo that validates that the output from
Ruby and `expo-modules-autolinking` is the same.

# Test Plan

✅ Red: differential test added first, failed with `unknown command
'prebuilt-metadata'`.
✅ Green: `pnpm exec jest e2e/__tests__/precompiled-derivations-test.ts`
— both tests pass (existing Ruby-vs-fixture snapshot + new TS-vs-fixture
differential)

# Checklist

- [x] Documentation is up to date to reflect these changes.
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…page (#49541)

# Why

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

# 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.
-->

<img width="2250" height="1162" alt="CleanShot 2026-08-31 at 12 52
52@2x"
src="https://github.com/user-attachments/assets/3ce670e7-0d09-424a-8270-be8b12583079"
/>


# 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).
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
…de (#48456)

# Why

Fixes #48442

Upstream issue - bumptech/glide#3550

When an image served from a server is invalid but is served with 200 OK
status code, Glide caches the invalid data bytes and never overrwites
it. When server returns correct data on the same URL, Glide won't serve
the new image until the cache is burst.

# How

- Provide a custom glide disk cache using disk cache configuration -
https://github.com/bumptech/glide/wiki/configuration#disk-cache
- In this custom disk cache, we override the default put method with a
delete and then put. Glide only calls this put method when it downloads
the data. The default put does not allow write if the key exists.

# Test Plan

- `et native-unit-tests -p android --packages expo-image`. The test
writes two payloads under one key and asserts the second wins; it fails
without the delete.
- Verified Image examples in NCL

# 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)
# Why

Document the authenticated `/simulator-sessions/create` URL so teams can
start browser-preview-only EAS Simulator sessions from pull requests, CI
results, and internal tools without integrating the REST API.

The guide also makes the action URL's immediate, non-idempotent behavior
explicit so readers do not accidentally create duplicate sessions or
share a creation link when they mean to share an existing session.

This documentation mirrors the merged website implementation in
[expo/universe#30640](expo/universe#30640), the
source of truth for the create-link URL contract.

# How

- Add a dedicated create session links guide with the URL contract,
application sources, additional parameters, URL encoding guidance, and
examples.
- Document `buildFingerprint`, its required `platform`, and how EAS
resolves it to the most recent installable build.
- Document empty source values and that `platform` is ignored for
`buildId` links.
- Document authentication, current iOS/browser-preview-only limitations,
validation behavior, session lifecycle, and the resulting shareable
session URL.
- Register the page in EAS Simulator navigation and link it from the
introduction and get-started pages.

# Test Plan

CI

# 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)
…Native 0.87 (#49600)

# Why

In BareExpo the `expo-modules` views are not rendering, that is because
they stopped receiving props on Android after React Native 0.87 moved
dynamic prop initialization from the `Props` constructor to the standard
component descriptor. We use a custom descriptor, leaving `rawProps`
empty and native views mounted and laid out but blank.

Should fix android e2e tests on main unless there is something else also
causing fails.

# How

Initialize dynamic props in
`AndroidExpoViewComponentDescriptor::cloneProps` using the previous
props and existing state prop filter before the map is consumed by
Android view manager.

# Test Plan

Run BareExpo - ExpoModules views now render correctly.
…tar pass (#49580)

# Why

`read_xcframework_info_plists_from_tarball` checks wether a prebuilt
artifact carry a slice for the platform we are building?

The problem with it is that it untars twice to find the answer:

It runs `tar tzf` to list the archive, selects the
`*.xcframework/Info.plist` entries, then runs `tar xOzf` once per entry.
`tar` decompresses a gzip stream from the start, so that is **1 + N full
decompressions** of an archive that also carries the dSYM bundles.

This happens for every prebuilt pod during Podfile evaluation, on every
`pod install`.

This came out of review on #49148, where the per-pod archive cost at
install time was raised as a concern. This half of the cost predates
that PR.

# How

Extract the whole glob in one pass into a temporary directory, then read
the plists off disk.

Every match is still read. That matters: a tarball can hold more than
one xcframework — the product plus a bundled SPM dependency, such as
SDWebImage inside `ExpoImage` — and the caller requires **all** of them
to support the target:

```ruby
info_plists.any? && info_plists.all? { |p| info_plist_supports_target_platform?(p) }
```

So stopping at the first match (bsdtar's `-q`) would be wrong here, and
is deliberately not used.

The fail-closed contract is kept and tightened. An unreadable archive
still yields `[]` so the pod falls back to source, and the two distinct
warnings are preserved — "No XCFramework Info.plist found" when the
archive simply has none, "Failed to inspect" when `tar` itself fails.

Three things changed after review:

- **A partial extraction is now a failure.** `tar` extracts in order, so
a truncated archive yields the first plist and then fails. Reading the
exit status only when zero plists came out returned a partial list
silently, which would have let the all-xcframeworks check pass on a
subset.
- **An unparsable plist now fails closed too.** It was previously
dropped by `filter_map`, so the same subset hole applied. Verified: a
tarball with one good and one unparsable plist reported the target as
supported. This is a deliberate behaviour change from the original
implementation, which also dropped it.
- **`/usr/bin/tar` is pinned.** The single-pass read relies on bsdtar's
member globbing; a GNU tar earlier in `PATH` would match nothing and
send every prebuilt pod to source.

This reduces the time per pod from 32.5 ms to 17.4 ms.

# Test Plan

`et check-packages expo-modules-autolinking` passes.

**Equivalence and timing over all 54 prebuilt tarballs in
`packages/precompile/.build`**, comparing the old implementation against
the new one in the same process:

```
tarballs: 54
results differ on: 0  (expect 0)
  old: list + N extracts       32.5 ms/tarball
  new: single pass             17.4 ms/tarball
```

Identical parsed output for every artifact, and roughly **1.9×** faster.
(An earlier revision of this description said 48 tarballs; that count
missed the scoped `@expo` packages, which nest a level deeper.)

**Failure handling**, covering the two holes found in review:

```
PASS  truncated archive -> [] (fail closed)
PASS  truncated archive -> "Failed to inspect"
PASS  truncated archive does NOT pass the platform check
PASS  garbage archive -> reports the tar failure, not "no plists"
PASS  valid archive without plists -> "No XCFramework Info.plist found"
PASS  corrupt plist among several -> [] (previously: a subset passed)
PASS  corrupt tarball no longer passes the platform check
```

**Multi-xcframework semantics**, the risk this change has to avoid. A
synthetic tarball holding two xcframeworks, where the product supports
iOS and the bundled dependency supports only macOS:

```
plists read: 2  (expect 2 — both must be read)
ids: ["ios-arm64", "macos-arm64"]
supports ios? false  (expect false — BundledDep is macos-only)
real artifact supports ios? true  (expect true)
missing tarball: []  (expect [])
```

If the change had silently read only the first plist, the third line
would have been `true` and the tarball would have been wrongly accepted.

# Checklist

- [x] I added a `CHANGELOG.md` entry
- [x] This diff will work correctly for `npx expo prebuild` & EAS Build
- [x] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com>
# Why

When a route is pushed to a stack in another tab the animation looks
weird. The route should push without animation, and there should only be
the animation of tab change.

This is the regression after global state refactor. 

# How

Whenever tab is changed native tabs router will append no animation
param to disable animation for leaf route (newly pushed/removed)

# Test Plan

1. CI
2. Router e2e


https://github.com/user-attachments/assets/ed9bb4b3-dafb-4ec6-835e-8cabbcacf614

# 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)
# Why

During global state refactor unnecessary wrapping was added to
`BaseNavigationContainer` and `NavigationContainer`

# How

<!--
How did you build this feature or fix this bug and why?
-->

# 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: Expo Bot <34669131+expo-bot@users.noreply.github.com>
# Why

Remove unused context

# How

<!--
How did you build this feature or fix this bug and why?
-->

# 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: jakub-agent <jakub-agent@expo.dev>
Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators Sep 1, 2026
@pull pull Bot added the ⤵️ pull label Sep 1, 2026
@pull
pull Bot merged commit 8a48e58 into code:main Sep 1, 2026
24 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.

10 participants