Skip to content

[pull] main from expo:main#654

Merged
pull[bot] merged 7 commits intocode:mainfrom
expo:main
Mar 6, 2026
Merged

[pull] main from expo:main#654
pull[bot] merged 7 commits intocode:mainfrom
expo:main

Conversation

@pull
Copy link

@pull pull bot commented Mar 6, 2026

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 : )

…parent" (#43691)

# Why

RNHostView should not call `super.addView` in `addView` since it renders
the child using `AndroidView` compose view. This can lead to below error
in some cases. e.g. RN mounts the child first and then compose tree
renders and tries to attach child to `AndroidView`.


```bash
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
                                                                                                    	at android.view.ViewGroup.addViewInner(ViewGroup.java:5286)
                                                                                                    	at android.view.ViewGroup.addView(ViewGroup.java:5115)
                                                                                                    	at android.view.ViewGroup.addView(ViewGroup.java:5055)
                                                                                                    	at android.view.ViewGroup.addView(ViewGroup.java:5027)
```

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

# How

Do not add view using view methods but put it in state and render it via
compose.

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

# Test Plan

Tested examples in NCL.


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

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

# Why

As it has been reported in #43485
only the brownfield library has explicit versions of React Native and
Hermes set

# How

- Extended setting RN and Hermes versions to all projects
- Added stripping "old" Hermes (`com.facebook.react:hermes-android`)
from POM - currently it's only stripped from module
- Enabled caching of resolved RN and Hermes versions, so that we don't
call `node ...` everytime we need them
- Cleaned up the code (by removing passing versions)
- Removed flaky logic for detecting brownfield project

# Test Plan

Created extended version of script from the issue, which validates both
POM and module:
https://gist.github.com/pmleczek/685261570033c3eeef804416056b927d

All versions are correctly set:
```sh
────────────────────────────────────────────────────────────────────────
com.swmansion.reanimated             4.2.2
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✗                .module: ✗          

────────────────────────────────────────────────────────────────────────
com.swmansion.worklets               0.7.4
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✗                .module: ✗          

────────────────────────────────────────────────────────────────────────
expo.modules.brownfield              55.0.11
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✗                .module: ✗          

────────────────────────────────────────────────────────────────────────
expo.modules.image                   55.0.5
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✗                .module: ✗          

────────────────────────────────────────────────────────────────────────
brownfield                           1.0.0
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✔ 250829098.0.7  .module: ✔ 250829098.0.7

────────────────────────────────────────────────────────────────────────
expo.core                            55.0.2
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✗                .module: ✗          

────────────────────────────────────────────────────────────────────────
expo.interfaces.devmenu              55.0.1
────────────────────────────────────────────────────────────────────────
  react-android     pom: ✔ 0.84.0         .module: ✔ 0.84.0   
  hermes-android    pom: ✗                .module: ✗          

...
```

Also verified that app consuming the artifacts compiles and works

# 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).
…43636)

# Why

Previously, the recursive dependency traversal doesn't stop at the depth
limit. Instead, it still uses that depth's information and prepares a
list of dependencies. However, it skips the (more expensive
`package.json` read step). This preserved more information and re-used
results at the maximum depth. However, this doesn't provide the version,
which is used and exposed via the `resolve` command. This can have an
impact on `@expo/fingerprint`.

Additionally, while it's not known which cases can cause
non-deterministic sorting, we can make non-deterministic outputs more
unlikely by:
- Sorting on `originPath` itself when depth of the dependency and depth
of the `originPath` match
- Load the `version` of duplicates regardless of `path` already having
been traversed (which is a duplicate `loadPackageJson` call, but the
memoisation should help here)

# How

While I didn't anticipate that `MAX_DEPTH = 8` would ever be exceeded by
native modules, there's two things we can cheaply do:
- Stop traversal at depth limit immediately to prevent creating
dependencies with unresolved `version: ''` entries
- Increase depth limit by +2 (+1 compensates for the traversal stop,
another +1 since hitting this bug means `MAX_DEPTH = 8` may have been
insufficient in some rare cases)

Additionally, there seem to be a reported case in #43517 of
non-deterministic outputs in edge cases with an unknown cause:
- We can further sort on `orginPath` to make this unlikely
- We can always load the `version` to make sure it's never missing

I've validated that for `router-e2e` this doesn't meaningfully increase
autolinking time by more than 5%.

# Test Plan

- Check the added unit test from #43517. Once the depth limit is
reached, we ignore further dependencies in the dependency tree, instead
of adding one more layer of dependencies with `version: ''`
- Manually run resolution in a sample app (e.g. `router-e2e`) against
`main` with hyperfine to quickly check the performance impact

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

---------

Co-authored-by: Dawid van der Hoven <dawidvdh@users.noreply.github.com>
Co-authored-by: Kudo Chien <kudo@expo.dev>
…3623)

# Why

Fix ENG-19921

This migration updates the docs from Tailwind CSS v3 to v4, along with
the companion `@expo/styleguide` packages that were updated for TW4
compatibility.

# How

**Core migration:**

- Upgrade `tailwindcss` from v3 to v4, replace `postcss-import` and
`autoprefixer` with `@tailwindcss/postcss`
- Upgrade `@expo/styleguide` v9 to v10, `@expo/styleguide-icons` v2 to
v3, `@expo/styleguide-search-ui` v3 to v4
- Convert `global.css` from `@tailwind` directives to `@import
"tailwindcss"` with `@config` reference
- Replace `eslint-plugin-tailwindcss` (TW3 only) with
`eslint-plugin-better-tailwindcss` (TW4 compatible), following
`@expo/styleguide`.

**TW4 syntax conversions**

- Convert TW3 important prefix syntax (`!p-0`, `!mb-0`) to TW4 suffix
syntax (`p-0!`, `mb-0!`)
- Convert TW3 gradient classes (`bg-gradient-to-b`) to TW4 syntax
(`bg-linear-to-b`)
- Reorder classes to match TW4 canonical ordering (handled by linter)

**TW4 variant composition fixes:**

- Fix `last:[&>*]:mb-0!` pattern in 4 files (`APICommentTextBlock`,
`APIBox`, `Collapsible`, `Requirement`). TW4 generates two selectors for
this pattern, one of which targets ALL children when the parent is
`:last-child`, instead of only the last child. Changed to
`[&>*:last-child]:mb-0!` which generates a single correct selector.
- Fix `last:[&>div>*]:mb-0!` and
`first:[&_figure]:mt-1`/`first:[&_pre]:mt-1` in `Tabs.tsx` with the same
approach.
- Remove `even:[&_blockquote]:bg-default` and
`even:[&_summary]:bg-element` from `Table/Row.tsx`. In TW3, these
generated selectors that never matched (e.g., `blockquote:nth-child(2n)`
instead of the intended parent-scoped selector). In TW4, they became
active and incorrectly overrode callout background colors (like
deprecated notice yellow backgrounds) on even table rows.

**Base layer fix:**

- Wrap bare HTML styles (`html`, `body`, `img`, `input`) in `@layer
base` so TW4 utility classes can properly override them.

# Test Plan

Run docs locally using `yarn run dev` and:
- Check the homepage, sidebar navigation, and Ask AI overlay panel for
visual correctness.
- Check large pages such as Expo Router and Expo Camera reference, Set
up your environment guide, app config reference, etc. where multiple
components are used.
- Compare the local dev site against `docs.expo.dev` for any visual
regressions.

# 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: Aman Mittal <10234615+amandeepmittal@users.noreply.github.com>
…ole (#43668)

# Why

Resolves ENG-19917


# How

**Component fix (`ui/components/VideoBoxLink/index.tsx`):**
- Include `description` in the JSON-LD schema when it's a plain string
(skips React elements to avoid serialization issues)
- Append `T00:00:00Z` to `uploadDate` to produce valid ISO 8601 datetime
with timezone, fixing both the "invalid datetime" and "missing timezone"
issues globally for all videos

**Missing videos added to `public/static/talks.ts`:**
- `-KZjr576tuE` ("How to quickly publish to the App Store & Play Store
with EAS Submit", 2023-05-30)
- `BCCjGtKtBjE` ("Expo Notifications with EAS | Complete Guide",
2024-09-11)
- `Gk7RHDWsLsQ` ("Automatic App Version Management", 2023-01-05)

**Added missing `description` props to `VideoBoxLink`:**
- `stripe.mdx` (latest, unversioned, v53, v54, v55)
- `background-task.mdx` (latest, unversioned, v53, v54, v55)
- `maps.mdx` (latest, unversioned, v53, v54, v55)
- `protected.mdx`, `ios-universal-links.mdx`, `image-picker.mdx`,
`create-your-first-app.mdx`, `create-a-build.mdx`

# Test Plan

View page source on any affected page (for example,
`/versions/latest/sdk/stripe/`) and confirm the `VideoObject` JSON-LD
block includes `description` and `uploadDate` with a `T00:00:00Z`
suffix. Validate the JSON-LD at
https://search.google.com/test/rich-results.

After deploying, click "VALIDATE FIX" in Google Search Console for each
of the 4 issues manually.

# 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: Aman Mittal <10234615+amandeepmittal@users.noreply.github.com>
Co-authored-by: Aman Mittal <10234615+amandeepmittal@users.noreply.github.com>
Co-authored-by: Aman Mittal <10234615+amandeepmittal@users.noreply.github.com>
@pull pull bot locked and limited conversation to collaborators Mar 6, 2026
@pull pull bot added the ⤵️ pull label Mar 6, 2026
@pull pull bot merged commit b887d67 into code:main Mar 6, 2026
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.

4 participants