Files
react-native/packages/core-cli-utils
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
..

@react-native/core-cli-utils

npm package

A collection of utilites to help Frameworks build their React Native CLI tooling. This is not intended to be used directly use users of React Native.

Usage

import { Command } from 'commander';
import cli from '@react-native/core-cli-utils';
import debug from 'debug';

const android = new Command('android');

const frameworkFindsAndroidSrcDir = "...";
const tasks = cli.clean.android(frameworkFindsAndroidSrcDir);
const log = debug('fancy-framework:android');

android
    .command('clean')
    .description(cli.clean.android)
    .action(async () => {
        const log = debug('fancy-framework:android:clean');
        log(`🧹 let me clean your Android caches`);
        // Add other caches your framework needs besides the normal React Native caches
        // here.
        for (const task of tasks) {
            try {
                log(`\t ${task.label}`);
                // See: https://github.com/sindresorhus/execa#lines
                const {stdout} = await task.action({ lines: true })
                log(stdout.join('\n\tGradle: '));
            } catch (e) {
                log(`\t ⚠️ whoops: ${e.message}`);
            }
        }
    });

And you'd be using it like this:

$ ./fancy-framework android clean
🧹 let me clean your Android caches
    Gradle: // a bunch of gradle output
    Gradle: ....

Features

  • "@react-native/core-cli-utils/version.js" contains the platform and tooling version requirements for react-native.

Contributing

Changes to this package can be made locally and linked against your app. Please see the Contributing guide.