174 Commits
Author SHA1 Message Date
Alex Hunt b26baaeba0 Move Community CLI discovery config into plugin package (1/2) (#58670)
Summary:
Replaces https://github.com/react/react-native/issues/57352.

Self-register commands from the `community-cli-plugin` package via `react-native.config.js` — meaning we can remove the redirect within `packages/react-native/react-native.config.js`.

Progress towards removing `community-cli-plugin` as a direct dep of `react-native`, and paired with https://github.com/react-native-community/template/pull/235.

RNTester and HelloWorld list `react-native/community-cli-plugin` in `devDependencies`, as the template now does (react-native-community/template#235).

Changelog:
[General][Breaking] - `react-native/community-cli-plugin` will no longer be auto-detected from `react-native`. It must now be specified in `devDependencies`.

Pull Request resolved: https://github.com/react/react-native/pull/58670

Test Plan:
Compared `react-native config` output with `react-native-community/cli` 20.2.0.

**RNTester**

- ✅ Commands, platforms, and project config are unchanged from `main`
- ✅ Removing the new `react-native/community-cli-plugin` devDependency drops `bundle`, `start`, `spm`, and `codegen`, so they are registered by plugin discovery

**Template-shaped app** (plugin in `devDependencies`, no project `react-native.config.js`)

- ✅ `bundle`, `start`, `spm`, and `codegen` are registered

Reviewed By: christophpurrer, cortinico

Differential Revision: D121634885

Pulled By: Abbondanzo

fbshipit-source-id: e97c9f820d3c597233ef4a7ddaaf1b752f1f7688
2026-09-25 09:05:12 -07:00
Sam Zhou 434a306c73 Cleanup legacy library types in xplat: 1/n (#58609)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/58609

Changelog: [Internal]

Differential Revision: D120838256

fbshipit-source-id: 1dd13e2748802bf50e6746257182fe1d0e4241ab
2026-09-20 10:52:30 -07:00
D N 97bea4625d Change default transform profile to 'hermes-stable' #2 (#57911)
Summary:
Issue: https://github.com/react/react-native/issues/57174
Initially, this PR was created to fix an issue above: https://github.com/react/react-native/pull/57208

 ---

But after re-testing it on the latest React Native `0.87.x`.
I found out that cli  set `unstable_transformProfile` value to `default`  (cli -> metro -> babel -> rn/babel-preset)

```tsx
function getTransformProfile(caller) {
  return caller?.unstable_transformProfile ?? 'hermes-stable';
                 ^^^ has a 'default' value (from CLI)
}
```

 ---

So, `isHermesProfile` is always `false` here:

https://github.com/react/react-native/blob/22cfb5caec78cb21b4a66b0ab82b03cc5f99a4dd/packages/react-native-babel-preset/src/configs/main.js#L63

and unnecessary babel plugins has applied

## Changelog:

[GENERAL] [CHANGED] - Change default transform profile to 'hermes-stable'

Pull Request resolved: https://github.com/react/react-native/pull/57911

Test Plan:
```java
npx react-native-community/cli init --pm yarn RN87
cd RN87
open node_modules/react-native/babel-preset/src/configs/main.js
// add Logs to print (isHermesProfile, transformProfile) vars

// Run build
./android/gradlew -p android assembleRelease
// Check logs (have to be `isHermesProfile: false, transformProfile: 'default')

// Apply fix
open node_modules/react-native/community-cli-plugin/dist/commands/bundle/index.js
// Find a `--unstable-transform-profile` option
// And change `default: "default",` => `default: "hermes-stable",`

 // Run build again
```

Reviewed By: christophpurrer

Differential Revision: D119189290

Pulled By: cortinico

fbshipit-source-id: e21ce35044d474b778f1fa8efe777ca0d9e37c7a
2026-09-09 03:44:00 -07:00
Janic Duplessis 74b984729b Fix asset catalog scale-to-file pairing for assets with non-standard scales (#57825)
Summary:
`saveAssets` filters an asset's scales through `filterPlatformAssetScales`, but `getImageSet` indexes the unfiltered `asset.files`, so an asset with scales `[1, 1.5, 2, 3]` gets the 1.5x file in its 2x catalog slot and the 2x file in its 3x slot: `Assets.car` ships the wrong images. An asset with no standard scale at all (only `1.5x`, say) produces an imageset actool silently drops from the car, which makes the image unloadable when `RCTUseAssetCatalog` is on, since the catalog runtime has no filesystem fallback (https://github.com/react/react-native/issues/30129).

Fix, in `assetCatalogIOS.js`:

- Each catalog slot (1x/2x/3x) is paired with its own file.
- An asset with no valid scale maps its closest variant into the nearest valid slot, the same "closest larger" rule loose files already get, and warns in the build log. Every imageset now holds at least one rendition actool will compile.

Related: expo/expo#48525 applies the same fix to Expo CLI's mirrored implementation.

## Changelog:

[IOS] [FIXED] - Asset catalog imagesets paired wrong files for assets with non-standard scales

Pull Request resolved: https://github.com/react/react-native/pull/57825

Test Plan:
New unit tests in `assetCatalogIOS-test.js`: standard 1x/2x/3x pairing, mixed `[1, 1.5, 2, 3]` (regression for the file shift), fractional-only `[1.5]`, and `[4]` clamping to the 3x slot.

```
yarn jest packages/community-cli-plugin/src/commands/bundle
Tests: 18 passed, 18 total
```

### End-to-end

Bundled a test app through the real pipeline (Metro → `saveAssets` → actool → `assetutil --info` on the compiled `Assets.car`) with two assets: `logo` at scales `[1, 1.5, 2, 3]` (100/150/200/300 px) and `star` with only a `1.5x` file (150 px).

| Rendition in `Assets.car` | before | after |
|---|---|---|
| `img_logo` 1x | 100 px | 100 px |
| `img_logo` 2x | **150 px (the 1.5x file)** | 200 px |
| `img_logo` 3x | **200 px (the 2x file)** | 300 px |
| `img_star` | **absent (actool dropped the `1.5x` imageset)** | 150 px in the 2x slot, with a build-log warning |

Running on an iPhone 17 Pro simulator (3x), same app built with the buggy and fixed CLI — the labeled tiles show which file the catalog actually served, and `star` goes from missing to rendering:

| Before | After |
|---|---|
| <img src="https://github.com/user-attachments/assets/4ebdbd33-74ec-4731-a2c4-f1a2d9b5838b" width="320" /> | <img src="https://github.com/user-attachments/assets/cd461b0a-5763-4388-8771-1ae6df383817" width="320" /> |

<details>
<summary>Repro app used for the screenshots</summary>

Built `private/helloworld` (Release, simulator) with `RCTUseAssetCatalog` set to `true` in its Info.plist, and these assets in `img/`, where each file is a solid tile with its scale label and pixel size baked into the image so a screenshot shows exactly which file got served: `logo.png` (100px, "1x"), `logo@1.5x.png` (150px, "1.5x"), `logo@2x.png` (200px, "2x"), `logo@3x.png` (300px, "3x"), and `star@1.5x.png` (150px, "STAR") with no other variants.

```js
// index.js
import React from 'react';
import {AppRegistry, Image, Text, View, StyleSheet} from 'react-native';

const styles = StyleSheet.create({
  root: {flex: 1, backgroundColor: 'https://github.com/react/react-native/issues/111', alignItems: 'center', justifyContent: 'center'},
  label: {color: '#fff', fontSize: 16, marginTop: 24, marginBottom: 8, fontWeight: '600'},
  box: {width: 100, height: 100, borderWidth: 2, borderColor: 'https://github.com/react/react-native/issues/666'},
  img: {width: 100, height: 100},
});

const App = () => (
  <View style={styles.root}>
    <Text style={styles.label}>logo.png (has 1x/1.5x/2x/3x)</Text>
    <View style={styles.box}>
      <Image style={styles.img} source={require('./img/logo.png')} />
    </View>
    <Text style={styles.label}>star.png (only 1.5x)</Text>
    <View style={styles.box}>
      <Image style={styles.img} source={require('./img/star.png')} />
    </View>
  </View>
);

AppRegistry.registerComponent('HelloWorld', () => App);
```

On the 3x simulator JS resolves `logo` to the 3x variant, so the tile that renders is the file the catalog's 3x slot actually contains: the 2x-labeled tile before the fix, the 3x tile after. `star` resolves to its only variant (`1.5x`); before the fix its imageset is dropped by actool and the box renders empty.

</details>

Reviewed By: christophpurrer

Differential Revision: D116956049

Pulled By: javache

fbshipit-source-id: 4405c235098ea7f8a4ebc03ca6876a3981894e71
2026-08-24 08:55:47 -07:00
Alex Hunt 97727ba67f Fix compat with extensionless scripts/* imports (#57718)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57718

**Context**

Replaces https://github.com/react/react-native/pull/57709, which identified a real bug in 0.87 from the combination of:

- https://github.com/react/react-native/pull/57276
- https://github.com/react/react-native/pull/57652

```
$ npx react-native spm add
error Cannot find module '.../node_modules/react-native/scripts/setup-apple-spm'

$ npx react-native codegen
error Cannot find module '.../node_modules/react-native/scripts/codegen/generate-artifacts-executor'
```

**This diff**

- Fix — and exclusively switch to — extensionless imports rather than requiring `.js`.
- Update in-repo consumers.

The previous single mapping is now an extension-aware mapping:
- `./scripts/*` now appends `.js`, so `react-native/scripts/foo` resolves to `foo.js`.
- `.sh` and `.rb` stay reachable via explicit `./scripts/*.sh` and `./scripts/*.rb` passthrough patterns.

**Impact**

- Explicit `react-native/scripts/*.js` specifiers no longer resolve, so JavaScript paths must be imported without an extension.
- Files under `scripts/` with extensions other than `.js`, `.sh`, or `.rb` are no longer exposed through `./scripts/*`.
    - These have no open source consumers.

Changelog:
[General][Fixed] - (RC4 only, drop for main changelog): `react-native/scripts/*` imports once again expand `.js` extensions
[General][Breaking] - Extensionless `react-native/scripts/*` imports are now **mandated**; explicit `.js` import specifiers are rejected.

Reviewed By: rubennorte

Differential Revision: D113898792

fbshipit-source-id: d72f60be2c08ab97871e336645856c9029e74ae2
2026-07-28 09:03:20 -07:00
Alex Hunt 14c3bd831d Drop legacy cli-server-api reference in dev server (#57653)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57653

Actions TODO comment dependant on https://github.com/react-native-community/cli/pull/2605 (landed).

This drops our local dependency on `react-native-community/cli-server-api` Flow types, as well as avoiding this transient dependency in end user projects.

**Other changes**

- Promote `debug` log to a user-facing `warn` — several features in RN will break/degrade in this case and we want to flag explicitly.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D113412986

fbshipit-source-id: a47c9cfea53a3f77259fd6c5fdbf48d953616377
2026-07-25 10:32:46 -07:00
Alex Hunt aee0ec3bd5 Relocate CLI plugin server modules (#57654)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57654

Reorganise these modules under a `src/dev-server/` directory (out of `src/(commands|utils)/`, more clearly identifying this unit of the codebase.

No public API change: the package still exports `startCommand` unchanged.

Renames inside this directory:

- `middleware.js` → `loadCommunityMiddleware.js`
- `runServer.js` → `runDevServer.js`

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D113412985

fbshipit-source-id: 9e27c7a02f057a37d702d5f13e55271244573d35
2026-07-25 10:32:46 -07:00
Alex Hunt cec7c453fb Move codegen and spm command wrappers into community-cli-plugin (#57652)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57652

Migrate the `codegen` and `spm` command wrappers (Community CLI specific) out of `react-native.config.js` and into the `react-native/community-cli-plugin` package, alongside the existing `bundleCommand` and `startCommand`.

This continues moving command definitions into the plugin so `react-native.config.js` becomes a thin routing layer, as the file's own comment already calls for.

**Changes**

- Add `src/commands/spm/index.js` and `src/commands/codegen/index.js`, each defining and default-exporting its command (unchanged `name`, `description`, and `options`) plus an exported args type — mirroring the `bundle`/`start` command structure.
- Export `spmCommand` and `codegenCommand` from `src/index.flow.js`.
- Drop the inline `spmCommand` and `codegenCommand` definitions from `react-native.config.js`.
- Add docs to README.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D113412987

fbshipit-source-id: a39a7ef208ee970f2b7f9d4c38a86c39752db09a
2026-07-25 10:32:46 -07:00
Alex Hunt 02315146f2 Remove commander dependency from main package (#57645)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57645

Simplify the `scripts/bundle.js` wrapper and remove the `commander` dependency from `packages/react-native`.

This script is a lightweight wrapper around `npx react-native bundle`, with extra local config arg handling (for now, unchanged / remains located here).

**Refactor only** with script behaviour unchanged.

**Other changes**

- Combined arg parsing is hoisted into `community-cli-plugin` (which does have `commander`) via `unstable_createBundleCommandParser`.
- Drop `program` value export (also unused).

**Notes**

After this change, only `yargs` remains as a direct dependency `react-native` package (`packages/react-native/scripts/`) (a future cleanup).

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D113389458

fbshipit-source-id: 09dbde6f86260bc8abdb8cb82ce1503ac6139952
2026-07-23 17:07:02 -07:00
Alex Hunt bf691fa53c Remove RN metro-config migration checks (#57648)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57648

Legacy check, clean up.

Changelog: [Internal]

___

Differential Revision: D113396915

fbshipit-source-id: 697b65f1a02a98949f490b2cc94d0864d52d1472
2026-07-23 06:52:14 -07:00
Alex Hunt 89300acb9c Migrate Node.js builtin imports to node: scheme (#57611)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57611

Directly follows D112733139 (Metro).

**Motivation**

- New Node builtins are *only* available under the prefix (e.g. `node:sqlite`), as this allows Node to introduce them without ecosystem-breaking changes, so this is the direction of travel and the only choice that'll allow consistency.
- Encouraging them and grouping them separately makes it easier to reason about a module's 3rd party dependencies.

Changelog: [Internal]

Reviewed By: robhogan

Differential Revision: D112803684

fbshipit-source-id: 40668d746a7151b3aa4800ff8af997902a18d198
2026-07-21 09:01:41 -07:00
Alex Hunt afa2a60c53 Restore react-native/setup-env references on main (#57560)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57560

Reverts D112002434.

This fix was needed on `0.87-stable` but not on `main`, since the `setup-env`-in-bundle-graph fix (https://github.com/react/react-native/pull/57492) was already present, see file at time of D112002434:

https://github.com/react/react-native/blob/08c323346be6c0fbbd70900d48435f977a78a1bb/packages/react-native/Libraries/Core/InitializeCore.js#L30-L37

See https://github.com/react/react-native/pull/57559 for more info.

Changelog: [Internal]

Reviewed By: zeyap

Differential Revision: D112101450

fbshipit-source-id: 435a24e72415e18b5e3d6a5144ed805adc415a95
2026-07-16 04:53:29 -07:00
Zeya Peng 08c323346b Bootstrap Metro from InitializeCore until setup-env is graph-reachable (#57557)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57557

Fresh projects **redbox on launch** — e.g.:

```
Failed to call into JavaScript module method RCTDeviceEventEmitter.emit().
Module has not been registered as callable.
Registered callable JavaScript modules (n = 1): AppRegistry.
```

(The named module varies — `HMRClient.setup()`, `RCTDeviceEventEmitter.emit()` — it's whichever callable module native calls first.) `n = 1: AppRegistry` is the tell: **core initialization never runs**.

## Root cause (https://github.com/react/react-native/issues/57475)

Core init runs via Metro's `serializer.getModulesRunBeforeMainModule`. Metro (`metro/src/lib/getAppendScripts.js`) only emits the run-before `__r()` for a module **already present in the bundle graph**, and silently skips it otherwise:

```js
const paths = [...options.runBeforeMainModule, entryPoint];
for (const path of paths) {
  if (modules.some((module) => module.path === path)) {  // only if already in the graph
    /* __r(moduleId) */
  }
}
```

**https://github.com/react/react-native/issues/57475** switched the run-before target from `Libraries/Core/InitializeCore` → `src/setup-env.js`.

- `InitializeCore.js` **is** reachable (imported by `Libraries/ReactPrivate/ReactNativePrivateInitializeCore.js`).
- `src/setup-env.js` is imported by **nothing** → not in the graph → silently skipped → core init never runs.

The two modules are functionally identical (both call `setUpDefaultReactNativeEnvironment().default()`), so only *reachability* changed. https://github.com/react/react-native/issues/57498 was cosmetic (same resolved file) and does not fix this.

### Evidence (bundle tail)

| Run-before target | Bundle tail | Boots? |
|---|---|---|
| `setup-env` (current) | `__r(0);` | ❌ |
| `InitializeCore` (this PR) | `__r(<InitializeCore>); __r(0);` | ✅ |

Verified end-to-end via `test-release-local -t RNTestProject -p iOS`. Ruled out: Metro cache (cold `--reset-cache` identical), stale Metro, and https://github.com/react/react-native/issues/57484 (`./src/*` exports removal). Reproduces via the `react-native-community/cli` bundling path (OSS `react-native start`); internal Meta bundling is unaffected, which is why CI/internal stayed green.

## Scope — interim stopgap

Only the **internal Metro bootstrap target** reverts to `InitializeCore`. The public `react-native/setup-env` entry point and its deprecation of `InitializeCore` are **unchanged**.

The **durable fix** is to make `setup-env` graph-reachable (or make Metro treat `getModulesRunBeforeMainModule` entries as graph roots) — which will then allow `InitializeCore` to be removed as intended. cc huntie (`setup-env` stack owner).

A cherry-pick of this is also up against `0.87-stable` (https://github.com/react/react-native/issues/57553).

## Changelog

[General][Fixed] - Fix apps failing to boot ("... not registered as callable") caused by core init not running.

Reviewed By: christophpurrer

Differential Revision: D112002434

fbshipit-source-id: ea3559ef74d31f2c0f9af78aa0a020f4b322e7e0
2026-07-14 23:00:36 -07:00
Rob Hogan fe511aba7c Bump Metro to 0.87.0 (#57534)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57534

Bump Metro to 0.87.0

Changelog:
[General][Changed] Bump Metro to 0.87.0

Reviewed By: huntie

Differential Revision: D111711509

fbshipit-source-id: 800fa83127d88db77948dab20b3edb574ecb5fc0
2026-07-13 11:06:41 -07:00
Alex Hunt 4237f1a90d Simplify react-native/setup-env require in community-cli-plugin (#57498)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57498

**Motivation**

While sanity checking https://github.com/react/react-native/pull/57492, I double checked why we use `path.join(ctx.reactNativePath, ...)` here when adjacent OOT platforms resolve by package name.

It turns out this complexity is historic and redundant:

- `reactNativePath` doesn't customize the `react-native` package name — it only resolves the `node_modules` directory. [[1]](https://github.com/react-native-community/cli/blame/main/packages/cli-tools/src/findPackageDependencyDir.ts#L81)
- We now (since ~2 years ago) resolve using `{paths: [ctx.root]}`, making the manual `path.join` redundant.

**This diff**

Drops the `reactNativePath` option and resolves `react-native/setup-env` directly by package name.

Purely a refactor. No need to pick to 0.87.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D111225671

fbshipit-source-id: ff0a385172228f51cde747266543cc615be7ee38
2026-07-10 06:08:44 -07:00
Alex Hunt bfa679f0ea Expose 'react-native/setup-env' to replace InitializeCore (#57475)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57475

NOTE: Resubmission of D110890810.

Replace `'react-native/Libraries/Core/InitializeCore'` with an explicit `'react-native/setup-env'` secondary export.

This was previously a special-case path excluded from our ESLint warnings. It is now formalised.

**Changes**

- Add new `src/setup-env.js` entry point and `package.json` mapping.
- Replace references in `packages/metro-config/` and `packages/community-cli-plugin/`.
- Update `warn-on-deep-imports` ESLint rule.

Changelog:
[General][Added] - Add `'react-native/setup-env'` entry point. This replaces the previous side-effectful `'react-native/Libraries/Core/InitializeCore'`.
[General][Deprecated] - Deprecate `'react-native/Libraries/Core/InitializeCore'`. Use `'react-native/setup-env'` instead.

Reviewed By: rubennorte

Differential Revision: D111022546

fbshipit-source-id: c9081997468b55b02c8a89544c7cb2026d625ad3
2026-07-08 09:33:30 -07:00
Emerson Berlik 904f0aeb66 Revert D110890810: Expose 'react-native/setup-env' to replace InitializeCore
Differential Revision:
D110890810

Original commit changeset: 3afe25efa455

Original Phabricator Diff: D110890810

fbshipit-source-id: 551c04d1e6c66e1d29938be3c2a7a57db475d589
2026-07-07 12:55:32 -07:00
Alex Hunt 554baba159 Expose 'react-native/setup-env' to replace InitializeCore (#57461)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57461

Replace `'react-native/Libraries/Core/InitializeCore'` with an explicit `'react-native/setup-env'` secondary export.

This was previously a special-case path excluded from our ESLint warnings. It is now formalised.

**Changes**

- Add new `src/setup-env.js` entry point and `package.json` mapping.
- Replace references in `packages/metro-config/` and `packages/community-cli-plugin/`.
- Update `warn-on-deep-imports` ESLint rule.

Changelog:
[General][Added] - Add `'react-native/setup-env'` entry point. This replaces the previous side-effectful `'react-native/Libraries/Core/InitializeCore'`.
[General][Deprecated] - Deprecate `'react-native/Libraries/Core/InitializeCore'`. Use `'react-native/setup-env'` instead.

Reviewed By: rubennorte

Differential Revision: D110890810

fbshipit-source-id: 3afe25efa45548d593a1b09c436e36038350b4c5
2026-07-07 10:43:04 -07:00
Rob Hogan 2b0107e0aa Bump Metro to 0.86.0 (#57453)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57453

Metro release notes:

https://github.com/react/metro/releases/tag/v0.86.0

Changelog:
[General][Changed] Metro to 0.86.0

Reviewed By: huntie

Differential Revision: D110789092

fbshipit-source-id: 4b999bf533c3c61b7915a73366ff3ca13257c3dc
2026-07-07 02:20:23 -07:00
Alex Hunt 41d52189e2 Create @react-native/asset-utils package (#57368)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57368

**Context**

This stack intends to relocate the `AssetRegistry` API from `react-native/assets-registry` into `react-native` — addressing runtime safety and public deep imports issues (1.0 and JS Stable API blockers).

**This diff**

Create a new `react-native/asset-utils` package, intended for internal/framework use (read: **will not be an end user concern**). This re-houses `react-native/assets-registry/path-support.js`.

Stacked with the next two diffs, this contributes to the 0.87 objective to delete `react-native/assets-registry` towards install-layout-safe behaviour and JS deep import removal.

- (Temporarily, this leaves two copies of `path-support.js` until I enact the package removal down the stack.)

This change also enables us to de-duplicate `assetPathUtils.js` inside `community-cli-plugin` and use one source of truth.

- Additionally, we have fbsource consumers of this util that cannot have a circular Buck dep on `react-native`, so the main package was not a suitable relocation point (secondarily to not adding an awkward new public API here).

**Changes**
- Add `react-native/asset-utils` (`packages/asset-utils/`): `src/AssetPathUtils.js` containing Android path helpers and tests.
- De-duplicate usages in `community-cli-plugin`: delete `src/commands/bundle/assetPathUtils.js`.

Changelog:
[General][Added] - Introduce `react-native/asset-utils` package (relocates Android path utils for libraries/frameworks)

Reviewed By: robhogan

Differential Revision: D110045272

fbshipit-source-id: 781e75c58ae9ce7f0fa860e66beca3b9990d26ea
2026-07-06 10:32:14 -07:00
Rob Hogan 014fe8b520 Refactor imports from Metro to avoid deprecated styles and prefer main package (#57378)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57378

Refactor Metro imports to:
 - Remove use of deprecated default object export, prefer named/namespace exports.
 - Prefer imports from `metro`, remove public dependencies on `metro-core` and `metro-config` from `react-native/community-cli-plugin`.

Changelog: [Internal]

Reviewed By: javache

Differential Revision: D110177050

fbshipit-source-id: f21a561d40d13f354bc56cdc50d6e6d6843877cc
2026-06-30 09:42:04 -07:00
Alex Hunt ae6a3afb22 Upgrade Metro to ^0.85.0 (#57335)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57335

Changelog: [Internal] - Node 22 requirement is synchronised with RN for 0.87

Reviewed By: robhogan

Differential Revision: D109699796

fbshipit-source-id: 642373a6babc37ce3e9bc83676abd0aa09f54a85
2026-06-25 10:31:30 -07:00
Alex Hunt ffe3f79495 Standardize secondary package READMEs (#57273)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57273

**Motivation**

A README is the first thing an npm visitor sees on each package; internal-repo boilerplate like the "Testing" sections and the "We're using yarn…" note doesn't belong on a published package page.

**Changes**

- Standardize every README: a `# react-native/<name>` heading, a user-facing description, and a blue version badge plus a green monthly-downloads badge.
- Keep the "internal dependency" prelude only on `community-cli-plugin`, `virtualized-lists`, and `js-polyfills`.
- Drop the monorepo-template "Testing" sections and yarn note.
- Rework `metro-config` around the Configuring Metro guide; add missing READMEs for `metro-babel-transformer` and `popup-menu-android`.

Changelog: [Internal]

Reviewed By: emily8rown

Differential Revision: D109017270

fbshipit-source-id: 6208294c4ad2e6235a6605ae54f22d730f0476e7
2026-06-18 07:04:44 -07:00
Rob Hogan dcbd8608a6 Update package.json references to GitHub org "facebook" -> "react" (#57258)
Summary:
Pull Request resolved: https://github.com/react/react-native/pull/57258

Reflecting the move to https://github.com/react/react-native , update references in first-party `package.json`s

The `repository.url` field in particular is load-bearing for Trusted Publish.

Changelog: [Internal]

___

Reviewed By: fabriziocucci

Differential Revision: D108986410

fbshipit-source-id: 78513ffefc32ddf417dc1479a4834ebc44240080
2026-06-18 02:00:52 -07:00
Sam Zhou 71fee907fb Turn on experimental.instance_t_objkit_fix across fbsource roots (#57234)
Summary: Pull Request resolved: https://github.com/react/react-native/pull/57234

Reviewed By: panagosg7

Differential Revision: D108750949

fbshipit-source-id: 1a72cf63dfa409309694c98404333bd24126f510
2026-06-16 13:38:46 -07:00
Alex Hunt a0d39e7a9c Bump minimum Node.js version to 22 (#56887)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56887

Drop support for Node.js 20. The minimum supported version is now `^22.13.0 || ^24.3.0 || >= 26.0.0`.

Node.js 20 reached end-of-life in April 2026 and is no longer actively maintained. This aligns React Native with the upcoming Metro requirement.

Changelog:
[General][Breaking] - Require Node.js >= 22.13.0

Reviewed By: christophpurrer, cortinico

Differential Revision: D105685641

fbshipit-source-id: f490e5a13e4289daba98c4d56dd8fdd341aef0db
2026-05-19 11:53:54 -07:00
Rob Hogan 783f45746e Bump packages to 0.87.0-main following 0.86 cut (#56716)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56716

Now that we've cut 0.86, bump all versions on `main` ready for the 0.87 cut.

Changelog: [Internal]

Reviewed By: cortinico, fabriziocucci

Differential Revision: D104219534

fbshipit-source-id: 86f2ebe5b44f67608a7a9495bf9840f2cdd52e5b
2026-05-07 07:23:06 -07:00
Moti Zilberman 7128482e49 Bump Metro to ^0.84.3 (#56638)
Summary:
Bumps Metro dependency from `^0.84.2` to `^0.84.3` across all packages.

Metro 0.84.3 adds `changeId` to HMR `update-done` messages, which is required by the `unstable_fastRefreshComplete` CDP event and the Fast Refresh performance marker to deduplicate events across multiple updates for the same file change.

## Changelog:

[Internal]

Pull Request resolved: https://github.com/facebook/react-native/pull/56638

Test Plan:
- CI

cc huntie

Reviewed By: cortinico

Differential Revision: D102810175

Pulled By: motiz88

fbshipit-source-id: b05bc522fd7815f2858ce645b03bdea86a8027ea
2026-04-28 22:50:41 -07:00
Alan Lee bbaabe6a16 Bump packages for next release (#55946)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55946

Follows the recent `0.85-stable` branch cut.

Changelog: [Internal] - Bump all packages to `0.86.0-main`

Reviewed By: cortinico

Differential Revision: D95410323

fbshipit-source-id: dacfee00f1111dbf57ef2e608963a4bffa669884
2026-03-10 00:35:59 -07:00
Rob Hogan 57d4b6b350 Update Metro to 0.84.2 (#55854)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55854

Notably, fixes a regression where `metro-config` (and therefore `react-native/metro-config` did not ship types, leaving untyped `metro.config.js`.

https://github.com/facebook/metro/releases/tag/v0.84.2

Changelog:
[General][Changed]: Update Metro to ^0.84.2

Reviewed By: cortinico

Differential Revision: D94901986

fbshipit-source-id: 02dc26ef0b8dcc67040d4d66dd22ef30d39a5bbf
2026-03-02 10:35:06 -08:00
Rob Hogan 58ed78fec1 Update Metro to 0.84.0 (#55672)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55672

Bump Metro minimum to 0.84.0

Although this is a semver-breaking release for Metro, that's only because of the slightly increased Node.js version requirements *already present in React Native*, so this bump is non-breaking for RN.

Full changelogs since previous bump:
https://github.com/facebook/metro/releases/tag/v0.83.4
https://github.com/facebook/metro/releases/tag/v0.84.0

Changelog: [General][Changed] Metro bump to ^0.84.0

Reviewed By: huntie

Differential Revision: D94020063

fbshipit-source-id: 4562517e726b9e2c7d803353ac083fd76a21c261
2026-02-23 08:29:45 -08:00
Alex Hunt f1bedfb92b Bump packages for next release (#55172)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55172

Follows the recent `0.84-stable` branch cut.

Changelog: [Internal] - Bump all packages to `0.85.0-main`

Reviewed By: vzaidman

Differential Revision: D90698490

fbshipit-source-id: b81b840bfd66e631f160a11c4c64baa6850e3393
2026-01-14 12:17:16 -08:00
Rob Hogan c9c601d61a Node.js: Drop support for Node.js versions released before 20.19.4, and EOL v21,v23 (#55114)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55114

Our official [docs](https://reactnative.dev/docs/set-up-your-environment#node--watchman) require:

> Node 20.19.4 or newer

Currently, our `package.json#engines` fields express this as `"node": ">= 20.19.4"`

This is a bit imprecise because of Node's overlapping release lines - e.g. v24.0.0 is actually older than v20.19.4 (2025-07-15), and the whole v21 line was already EOL before v20.19.4.

The release *date* is relevant because Node.js frequently backports the most important updates - notably, `require(esm)` is already stable in Node 20.19 but is not unflagged in v22 until v22.12.

This makes the `package.json#engines` requirement truer to the documented requirement, dropping some old minors and EOL majors that prevent us using features included in v20.19.

Notably, `require(esm)` is stable and unflagged on all versions supported from this diff.

 - v21 and v23 are EOL, so are dropped.
 - v22.13 pre-dates 20.19.4 and is the first to have unflagged silent `require(esm)`
 - v24.3.0 pre-dates 20.19.4 and is the first to unflag TS-stripping
 - Support v25 and newer.

Changelog:
[General][Breaking] Drop support for EOL Node.js lines and old minors.

Reviewed By: cortinico, huntie

Differential Revision: D90467358

fbshipit-source-id: a5fdfb1b93a9d6cffe78eb6811ff7420ab906f44
2026-01-14 10:49:05 -08:00
Marco Wang 7051a07c63 Transform $ReadOnlyArray to ReadonlyArray 17/n (#55109)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55109

We are transforming the following utility types to be more consistent with typescript and better AI integration:

* `$NonMaybeType` -> `NonNullable`
* `$ReadOnly` -> `Readonly`
* `$ReadOnlyArray` -> `ReadonlyArray`
* `$ReadOnlyMap` -> `ReadonlyMap`
* `$ReadOnlySet` -> `ReadonlySet`
* `$Keys` -> `keyof`
* `$Values` -> `Values`
* `mixed` -> `unknown`

See details in https://fb.workplace.com/groups/flowlang/permalink/1837907750148213/.

drop-conflicts

Command:

`js1 flow-runner codemod flow/transformUtilityType --legacy-type='$ReadOnlyArray'`

Reviewed By: SamChou19815

Differential Revision: D90402950

fbshipit-source-id: d338ad7997728d40457b1199c3bd5dcd245a39c3
2026-01-13 20:33:09 -08:00
Rob Hogan 0cda10b00a Revert: Bump minimum Node.js version to v22.11 (prev LTS) (#55113)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55113

Reverts https://github.com/facebook/react-native/pull/55038

Dropping v20 (still in LTS) causes friction with Expo's LTS policy, so we're restoring support for v20.19.

Changelog: [General][Added] Revert https://github.com/facebook/react-native/pull/55038

Reviewed By: shwanton

Differential Revision: D90467161

fbshipit-source-id: d876cf7869f11e04058f88239f553704e0706514
2026-01-11 14:30:40 -08:00
Tommy Nguyen 42986f27a0 fix(android): support unstable_path query param in asset URLs (#55072)
Summary:
Syncs `getAndroidResourceIdentifier` implementations between [`/community-cli-plugin/src/commands/bundle/assetPathUtils.js`](https://github.com/facebook/react-native/blob/main/packages/community-cli-plugin/src/commands/bundle/assetPathUtils.js#L72-L79) and [`/assets/path-support.js`](https://github.com/facebook/react-native/blob/main/packages/assets/path-support.js#L77-L85).

Ideally, the former should use `react-native/assets-registry` directly so we don't need to sync.

## Changelog:

[ANDROID] [FIXED] - Handle `unstable_path` query param in asset URLs

Pull Request resolved: https://github.com/facebook/react-native/pull/55072

Test Plan: n/a

Reviewed By: javache

Differential Revision: D90267467

Pulled By: Abbondanzo

fbshipit-source-id: f4eb0053c6af02b67f3fb493ae76e290d6b354e5
2026-01-07 13:47:01 -08:00
Marco Wang 1cc30dc1ad Transform $ReadOnly to Readonly 37/n (#55066)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55066

We are transforming the following utility types to be more consistent with typescript and better AI integration:

* `$NonMaybeType` -> `NonNullable`
* `$ReadOnly` -> `Readonly`
* `$ReadOnlyArray` -> `ReadonlyArray`
* `$ReadOnlyMap` -> `ReadonlyMap`
* `$ReadOnlySet` -> `ReadonlySet`
* `$Keys` -> `keyof`
* `$Values` -> `Values`
* `mixed` -> `unknown`

See details in https://fb.workplace.com/groups/flowlang/permalink/1837907750148213/.

drop-conflicts

Command:

`js1 flow-runner codemod flow/transformUtilityType --legacy-type='$ReadOnly'`

Changelog:[internal]

Differential Revision: D90146145

fbshipit-source-id: 4b71784a36f8286f3be620969ea408cf8a0aac80
2026-01-06 18:57:56 -08:00
Rob Hogan 8f10b339d4 Breaking: Bump minimum Node.js version to v22.11 (prev LTS) (#55038)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/55038

Bump the minimum to Node.js v22.11, which is the previous LTS now that v24 is in LTS. Drop support for Node v20.

https://nodejs.org/en/blog/release/v22.11.0
https://nodejs.org/en/about/previous-releases

Changelog: [General][Breaking] Bump minimum Node.js version to v22.11

Reviewed By: cortinico, huntie

Differential Revision: D90109056

fbshipit-source-id: 178f29d3131f21fccf956decc9ac94365a2bfe53
2026-01-05 06:21:25 -08:00
Marco Wang 2624e2f52e Transform mixed to unknown in xplat/js (#54955)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54955

We are transforming the following utility types to be more consistent with typescript and better AI integration:

* `$NonMaybeType` -> `NonNullable`
* `$ReadOnly` -> `Readonly`
* `$ReadOnlyArray` -> `ReadonlyArray`
* `$ReadOnlyMap` -> `ReadonlyMap`
* `$ReadOnlySet` -> `ReadonlySet`
* `$Keys` -> `keyof`
* `$Values` -> `Values`
* `mixed` -> `unknown`

See details in https://fb.workplace.com/groups/flowlang/permalink/1837907750148213/.
drop-conflicts

Reviewed By: SamChou19815

Differential Revision: D89581584

fbshipit-source-id: cc5953ffea6cf1060f69efc714508e8ba93a040c
2025-12-22 12:25:44 -08:00
Alex Hunt cc9164c337 Move JavaScript exports rewrites to publishConfig/prepack (#54857)
Summary:
### Motivation

Updates the shared JavaScript build setup to use the modern `publishConfig` convention.

This:

- Simplifies the build script.
- Makes the production values for `"exports"` more understandable in place (especially by separating from exports conditions).
- Prevents us from creating a dirty file state when running `yarn build`.

### Changes

- Add `publishConfig` to each `package.json` listing production `"exports"` targets.
- Add `scripts/build/prepack.js` script to action `publishConfig` (now on `npm pack`, `npm publish` exclusively).
- Remove `"exports"` rewriting (and un-rewriting safeguards) from build script.

**Note on `"prepack"`**

Slightly unfortunately, `publishConfig` doesn't work consistently between package managers currently, including npm — so this does not work implicitly (but may in future).

We're instead following `publishConfig` as a convention, and explicitly implementing a full copy (theoretically forking us towards pnpm and Yarn v4's approach).

However, I believe this is:

- Worthwhile, for the motivations above — and in particular being able to understand the final shape of `"exports"` (independent from the dimension of conditional exports, which may come into play later).
- Completely inspectable/maintainable as an explicit implementation (`scripts/build/prepack.js`).

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/react-native/pull/54857

Test Plan:
### CI

✅ GitHub Actions

### End-to-end release test script

(Note: Rebased on `0.83-stable` when tested)

```
yarn test-release-local -t "RNTestProject" -p "iOS" -c $GITHUB_TOKEN
```

{F1984106139}

✅ Test script runs `npm publish` on packages to a local proxy.

{F1984106146}

✅ Installed packages have `publishConfig` `"exports"` values applied

NOTE: ⬆️ This is **exactly** the same output as before.

 {F1984106148}

✅ `/tmp/RNTestProject` runs using built + proxy-published + proxy-installed packages

Reviewed By: cipolleschi

Differential Revision: D88963450

Pulled By: huntie

fbshipit-source-id: f328252cf93a1f1039b79d7f369d1e6e7e5b4b52
2025-12-12 04:08:59 -08:00
Anthony Bajoua f472ef980a Allow Heif/Heic Assets (#54640)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54640

# Summary:
Trying to add heif/heic files to the ReactVRPlayground but they are not included to metro.

Codegen via

```
js1 build buckfiles
arc build
```

Insired by D58261501

Changelog:
[General][Added] - Bundle support for heic and heif files
___

overriding_review_checks_triggers_an_audit_and_retroactive_review
Oncall Short Name: vr_metacam

Reviewed By: lenaic, robhogan, javache

Differential Revision: D86807752

fbshipit-source-id: 0fd2271f46dc8bc5d568360c50dcd2db067923f6
2025-11-25 12:59:49 -08:00
Alex Hunt a1e534a604 Bump packages for next release (#54452)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54452

Follows the recent `0.83-stable` branch cut.

Changelog: [Internal] - Bump all packages to `0.84.0-main`

Reviewed By: cipolleschi

Differential Revision: D86534507

fbshipit-source-id: 47b88dce919857398f41516d03d60259730d2887
2025-11-12 04:22:19 -08:00
David Prevost 6addea5d0c fix(community-cli-plugin): Add description in target debugs to distinguish RN Bridge and reanimated (#54198)
Summary:
As I point out in this [issue](https://github.com/facebook/react-native/issues/50696#issuecomment-3418457545), when integrating reanimated, we end up with two debug targets having the same title. This can confuse and lead people to think something is wrong.

Adding the description alongside the title to better explain where the second debug target comes from eliminates the confusion.

Changelog: [Internal]

Pull Request resolved: https://github.com/facebook/react-native/pull/54198

Test Plan:
Tested in [this RN 82 project](https://github.com/dprevost-LMI/rn82/tree/reanimated) with the latest reanimated by overriding the code in the `node_module`

Before:
<img width="406" height="94" alt="Screenshot 2025-10-18 at 10 52 18 AM" src="https://github.com/user-attachments/assets/e517bf53-5176-479f-9fbb-3f4b46089395" />

After:
<img width="522" height="78" alt="Screenshot 2025-10-18 at 10 56 27 AM" src="https://github.com/user-attachments/assets/aa14aebd-4c13-4249-bb00-63972302ab40" />

Reviewed By: hoxyq

Differential Revision: D85041647

Pulled By: huntie

fbshipit-source-id: 0a1cc9cc2fb0fadf31c8c60de19d77cfb01d072a
2025-11-06 10:57:33 -08:00
Rob Hogan 89f0a37800 Minor bump Metro to ^0.83.3 (#54010)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54010

Bump Metro minimum to 0.83.3

This release fixes a regression in loading config files that export promises.

Full changelog: https://github.com/facebook/metro/releases/tag/v0.83.3

Changelog:
[General][Changed] Metro bump to ^0.83.3

Reviewed By: vzaidman

Differential Revision: D83655569

fbshipit-source-id: 106a957620e4591ef3cce21d327886354913560b
2025-10-02 06:53:57 -07:00
Nicola Corti d9a582e949 Bump packages to 0.83.0-main (#54009)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/54009

Packages haven't been bumped on main ahead of 0.83. This takes care of it.

Changelog:
[Internal] [Changed] -

Reviewed By: cipolleschi, huntie

Differential Revision: D83580515

fbshipit-source-id: 7471e77f74e3fb3b4ee6538a49369b5df1393098
2025-10-01 07:13:33 -07:00
Vitali Zaidman 3a954caf4f don't require projectRoot in devMiddleware (#53921)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53921

Changelog: [Internal] `devMiddleware` removed the unused option `projectRoot`

This option was used only in a dead branch of the code inside `InspectorProxy`.

The scenario where it appeared was enabling resolving script sources (`Debugger.getScriptSource`) starting with `file://` which were coming from the file system. However, we don't seem to ever point scripts at the filesystem this way.

Reviewed By: huntie

Differential Revision: D82739662

fbshipit-source-id: 9a130eaa83cb94ae0e36a5a1102c56ff8a36cffc
2025-09-24 12:47:24 -07:00
Sam Zhou 4365c1c9f7 Cleanup codeless suppressions in xplat/js (#53573)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53573

Changelog: [Internal]

Reviewed By: marcoww6

Differential Revision: D81552699

fbshipit-source-id: 71b104174a8ad7fbf360cdd87109ce034f49ec70
2025-09-02 21:56:09 -07:00
Phil Pluckthun b054540092 Mark @react-native/metro-config as optional peer to fix warning (#53314)
Summary:
The `react-native/metro-config` peer was added in https://github.com/facebook/react-native/commit/fe2bcbf4ba7ce983fac0cd09727c165517b6337f / https://github.com/facebook/react-native/issues/51836 by robhogan

Side-note: It's pulled in via `react-native/community-cli-plugin` which is a direct dependency of `react-native` for the `scripts/bundle.js` script. While, for expo, we'd love to find a way to make this an optional dependency (to avoid excessive deps that `expo` replaces otherwise), for now, it's a direct dependency.

The problem here is that this isn't optional, which means:
- with auto-installing peer dependencies it is directly fulfilled (while `react-native-community/cli` is already marked as optional and skipped)
- with legacy/non-auto peer-dependencies it is flagged as missing, but in an Expo project it wouldn't make sense to install directly

This causes a **package manager regression in the form of either a peer dependency warning**, that shouldn't be fulfilled in an Expo project, or (in the best case scenario) pulls in dependencies [that a user does not need](https://npmgraph.js.org/?q=%40react-native%2Fmetro-config#zoom=w&select=exact%3A%40react-native%2Fmetro-config%400.81.0).

An error message is already in place to inform the user of this being missing when it's not installed, so marking it as optional seems appropriate.

## Changelog:

[INTERNAL] [FIXED] Mark added `react-native/metro-config` peer dependency as optional

<!-- Help reviewers and the release process by writing your own changelog entry.

Pick one each for the category and type tags:

[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message

For more details, see:
https://reactnative.dev/contributing/changelogs-in-pull-requests

Pull Request resolved: https://github.com/facebook/react-native/pull/53314

Test Plan:
Warnings like the following won't occur in fresh Expo (54/preview/`next`) projects
```
warning "workspace-aggregator-484d9ec3-587b-43cb-97de-4dcce3876578 > microfoam-mobile > react-native > react-native/community-cli-plugin@0.81.0" has unmet peer dependency "react-native/metro-config@*".
```

Reviewed By: cortinico

Differential Revision: D80450287

Pulled By: robhogan

fbshipit-source-id: c622fd4c24025676c0ec74de826f863f1e291669
2025-08-24 14:18:42 -07:00
Sam Zhou 0530ea3349 Migrate to suppression with error code in xplat: 1/n (#53439)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53439

Changelog: [Internal]

Reviewed By: panagosg7

Differential Revision: D80809220

fbshipit-source-id: 6f432d8302934b9fee9780ac1d6ba6c87c0b3899
2025-08-22 10:35:39 -07:00
Sam Zhou cf664c65e2 Standardize subtyping error code into incompatible-type in react native and metro (#53312)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/53312

Changelog: [Internal]

Reviewed By: jbrown215

Differential Revision: D80400976

fbshipit-source-id: 196af69c0b9621b2a2675b232406639773e04933
2025-08-18 09:04:31 -07:00