Mishal Ibrar
000
Back to work
CLI2026Creator & Maintainer

(03) — case study

RN Arch Check

React Native New Architecture Compatibility Checker

A zero-config CLI that checks every dependency in a React Native or Expo project against React Native Directory and reports which ones support the New Architecture. It sorts the report by what needs action, quotes npm deprecation notices the directory does not track, and exits non-zero only on a confirmed incompatibility so it can gate CI.

Native packages per scan
64Native packages per scan
Full dependency check
2sFull dependency check
CI gate on incompatibility
Exit 1CI gate on incompatibility
RN Arch Check — React Native New Architecture Compatibility Checker
Node.jsReact NativeExponpmReact Native Directory APICI

(01) — the build

Overview

rn-arch-check is a command-line tool that checks every dependency in a React Native project against React Native Directory and reports which ones support the New Architecture, meaning Fabric, TurboModules and JSI. It answers the migration question before the build breaks rather than after, and it runs with npx rn-arch-check.

Every migration guide gives the same advice: open React Native Directory and cross-reference it against package.json by hand. This does that automatically, for every dependency at once, in about two seconds, and exits non-zero when something is confirmed incompatible so it can gate CI.

The New Architecture is the default from React Native 0.76 and Expo SDK 52 onward, and the old architecture is on its way out, but plenty of third-party packages still have no confirmed support.

The Challenge

Checking New Architecture readiness by hand means searching the directory once per dependency, then reading each result carefully, because the data has sharp edges:

  • The search response only carries a newArchitecture field for some entries
  • Popular libraries such as react-native-screens omit it entirely
  • Classifying on that field alone reports them as unverified
  • The directory records compatibility but knows nothing about deprecation
  • A package can read Compatible while npm tells you to move off it
  • The directory drops connections when too many requests land at once

A checker that verifies less than it appears to is worse than no checker, so the tool had to be explicit about what it could and could not confirm.

Solution

The scan runs in four stages.

  • Scan: reads dependencies and devDependencies from package.json, since a native module in devDependencies still ends up in the build
  • Filter: skips packages with no native code, including pure-JavaScript libraries, tooling and React Native's own framework packages
  • Check: looks each remaining package up against React Native Directory, alongside a small npm registry lookup for deprecation
  • Report: groups results by severity and prints the packages you must act on first

When the directory omits the newArchitecture field, the tool makes one extra request using the API's authoritative newArchitecture=true filter. Most packages therefore cost one request and ambiguous ones cost two.

Status Meanings

  • Compatible: confirmed New Architecture support in React Native Directory
  • Incompatible: explicitly marked as not New Architecture ready
  • Unverified: listed in the directory, but support is not confirmed either way
  • Unlisted: not found in the directory
  • Unknown: the lookup failed, so re-running retries it

A package marked New Arch only is compatible, but requires the New Architecture, so it will not work on the old one.

Deprecation Awareness

Every package is also checked against the npm registry, and any deprecation notice is printed verbatim, because the notice usually names the successor. Deprecation does not affect the exit code, since it is a maintenance signal rather than a compatibility one. The npm lookup is best-effort and never fails a scan.

What A Real Scan Turns Up

Pointed at a production app with 93 dependencies, the tool checked the 64 native ones in about two seconds and skipped 29 as pure JavaScript. The result was 54 compatible, 8 unverified, 1 confirmed incompatible and 1 unlisted native module.

The incompatible package was not the interesting finding. Seven dependencies reported Compatible or Unverified while having been abandoned for two to five years, and one reported Compatible while npm had formally deprecated it in favour of a successor. A compatibility flag records whether a package works today. It says nothing about whether anyone is left to fix it when the next React Native release breaks it.

CI Behaviour

Exit codes are deliberately narrow, so the tool gates a pipeline with no configuration beyond the command itself.

  • 0: no confirmed incompatibilities
  • 1: at least one dependency is confirmed incompatible
  • 2: the scan could not run, or every lookup failed

Unverified results never fail the build, and a scattering of failed lookups does not either. A run where every lookup failed exits 2 rather than 0, so an offline or blocked CI runner cannot report a clean pass having verified nothing.

Concurrency And Retries

The directory API is the bottleneck, not the client. Measured on a 15-package project, raising concurrency to 20 caused 7 of 15 lookups to fail outright, producing a faster scan that quietly verified less. Each lookup is therefore retried twice with a short backoff, which cleared those failures at every concurrency level tested, and the default concurrency stays at 5.

Key Features

  • Zero configuration, reads package.json with no setup
  • Nothing to install, runs straight from npx
  • CI-ready, exit code 1 on a confirmed incompatibility
  • Deprecation-aware, flags packages npm has deprecated
  • Severity-sorted report, with raw JSON output for pipelines
  • Expo and bare React Native both supported

Tech Stack

  • Runtime: Node.js 18.17+
  • Target: React Native, Expo
  • Data sources: React Native Directory API, npm registry
  • Output: formatted terminal report, JSON mode for CI
  • Testing: mock project fixture and stubbed directory API, so the suite needs no network

Scope And Limits

The tool reads the dependencies and devDependencies declared in package.json, the packages you chose, and does not walk the lockfile. A native module pulled in only as someone else's transitive dependency will not appear in the report. In practice that is rarely where migration risk lives, because native modules are almost always direct dependencies.

It only reads package.json. It never installs, writes or changes anything in the project.

How It Compares

On an Expo project, expo-doctor already runs a React Native Directory check as part of its wider project validation, and it is first-party tooling that is already installed. rn-arch-check exists for the cases outside that: a bare React Native app with no Expo installed, or a focused New Architecture gate in CI that fails on a confirmed incompatibility and nothing else, with npm deprecation surfaced alongside.

The Result

An MIT-licensed open-source CLI that turns a manual, per-package cross-reference into a two-second scan, with a report sorted by what actually needs action and an exit code a pipeline can trust.

Industry
Developer Tooling
Platform
CLI (Node.js) for React Native and Expo
Role
Creator & Maintainer
Duration
2026
Updated
August 2026

Screen patterns

  • Dependency Scan
  • Directory Lookup
  • Severity-Sorted Report
  • CI Gate

User flows

  • package.json Scan Flow
  • Ambiguous Lookup Resolution
  • Exit Code Decision

Key UI elements

  • Status Legend
  • Deprecation Notice Block
  • JSON Output Mode
  • Concurrency Control

Stack

  • Node.js
  • React Native
  • Expo
  • npm
  • React Native Directory API
  • CI