CodeVetter
← All unpacks
CodeVetter · Repo Unpack evidence

facebook/react

Scanned commit 59aff3e18c dated 2026-09-18 — last upstream commit. Generated by codevetter 1.12.0 on 2026-09-22.

github.com/facebook/react ↗ · 4000 files · 24.3 MB · scan capped

React · React is a JavaScript library for building user interfaces.

Deep analysis by claude-opus-5 via the claude CLI on 2026-09-22 (485s) — every claim below links to its cited source files.

Overview

This is the facebook/react monorepo at commit 59aff3e — the React runtime (isomorphic `react`, the Fiber reconciler, the Fizz SSR server, the Flight/Server-Components client+server, DevTools, and the Scheduler) plus a largely independent `compiler/` sub-project holding the React Compiler in both TypeScript (`babel-plugin-react-compiler`) and an in-progress Rust port (12 `react_compiler_*` crates behind a napi bridge). It is a library-publishing repo, not an app: nearly every artifact is a Rollup-built npm bundle produced per *release channel* (stable / canary / experimental / www-classic / www-modern / xplat), with behaviour toggled by ~67 `enable*` feature flags that are fork-substituted at build time. What is distinctive is the fork/shim architecture — `ReactFiberConfig`, `ReactFeatureFlags`, `ReactFlightServerConfig` and friends are placeholder modules that *throw* unless Rollup or Jest swaps in a renderer-specific implementation — and a CI matrix that runs the same Jest suite 18 ways × 5 shards to prove every channel behaves.

System map

There is no single entrypoint; the repo is a set of publishable packages under `packages/` (workspace glob in `package.json`) plus a nested Yarn/Cargo workspace under `compiler/`. The public runtime entrypoints are `packages/react/index.js` (isomorphic), `packages/react-dom/client.js` → `ReactDOMRoot.createRoot`, `packages/react-dom/server.node.js` → Fizz, and `packages/react-server-dom-*/server.*` → Flight. Everything is compiled by `scripts/rollup/build.js`, driven by a bundle table in `scripts/rollup/bundles.js` and a module-substitution table in `scripts/rollup/forks.js`; `build-all-release-channels.js` runs the whole thing once per channel and rewrites versions from `ReactVersions.js`. There is no database or persistent storage layer — the only 'storage' is the Fiber tree in memory, npm as the deployment target, and GitHub Actions artifacts. Tests never run `jest` directly; `scripts/jest/jest-cli.js` picks one of six configs and spawns Jest with channel/env/variant globals injected.

All 14 system map claims →

Feature catalog

User-facing surface is API surface, not screens. `packages/react/src/ReactClient.js` is the canonical export list for the isomorphic package; `react-dom` fans out to client, server (Node/Edge/Browser/Bun), static prerender and test-utils entrypoints; `react-server-dom-{webpack,turbopack,parcel,esm,unbundled,fb}` each ship a bundler-specific Flight client+server pair. Tooling packages are first-class features too: `eslint-plugin-react-hooks` (now also re-exporting compiler-derived rules), `react-refresh` (Fast Refresh Babel plugin + runtime), DevTools in five packaging flavours, and two MCP servers. Behaviour is further gated by ~67 `enable*` flags in `packages/shared/ReactFeatureFlags.js`, inspectable via `yarn flags`.

All 15 feature catalog claims →

Data flow

On the client, input enters through DOM events (delegated at the root by `listenToAllSupportedEvents`) or imperative `root.render`, both of which funnel into `scheduleUpdateOnFiber(root, fiber, lane)`. State lives on the Fiber tree hanging off `FiberRoot`; the `lane` bitmask on `ReactFiberLane.js` is the priority currency that decides whether work is flushed synchronously, in a microtask, or via a Scheduler task. Output boundaries are the host config (`ReactFiberConfig`, substituted per renderer) and, for SSR/RSC, the stream `Destination` in Fizz/Flight. Cross-module state is deliberately routed through a single mutable singleton, `ReactSharedInternals` (`.H` = current hooks dispatcher, `.T` = current transition, `.A` = async dispatcher), which is itself a forked module so client and server get different instances.

All 15 data flow claims →

Behavior traces

Three flows are worth walking: (1) client startup/first paint, from `createRoot` through the microtask scheduler into render and commit; (2) the compile flow, where Babel hands a function to either the TS `Pipeline.ts` or the Rust `pipeline.rs`; (3) the release flow, where a commit becomes npm artifacts. The commit phase in particular is a fixed three-pass sequence with `root.current = finishedWork` as the atomic swap point between mutation and layout, and passive effects flushed later. Each trace below names the functions in call order with line anchors.

All 15 behavior traces claims →

Testing signals

Jest 30 is the runtime test framework, with 544 test files under `packages/**/__tests__`, and it is deliberately unusable directly — `package.json`'s `testRegex` points at `dont-run-jest-directly.js`, forcing everything through `scripts/jest/jest-cli.js`. That CLI selects one of six configs (source, source-www, source-xplat, source-persistent, build, build-devtools) and injects `__DEV__`, `__EXPERIMENTAL__` and `__VARIANT__` globals; individual tests opt in/out of behaviour with `// @gate <flag>` pragmas resolved by `scripts/jest/TestFlags.js`. The compiler uses a different harness entirely: `yarn snap` over ~1,543 fixture files with `.expect.md` snapshots, plus Playwright e2e for the playground and the flight fixture. CI runs the runtime suite as an 18-config × 5-shard matrix; the Rust port has its own workflow gating on `cargo check`, `cargo build`, two shell test scripts and `yarn snap --rust`.

All 15 testing signals claims →

Risk map

The genuinely security-sensitive surface is small but sharp: Flight's Server Actions turn attacker-controlled FormData into a module lookup and function invocation, the taint registry is the only guard against serialising server secrets to the client and it is experimental-only, and the DevTools extension bridges page-world `postMessage` to privileged `chrome.runtime` ports while also running string-`eval` payloads through `chrome.devtools.inspectedWindow.eval`. Operationally the biggest fragility is the fork/shim system — `ReactFiberConfig` and `ReactFeatureFlags` resolve differently under Rollup, Jest and Flow, so a change that passes locally can break a channel nobody ran. `ReactFiberWorkLoop.js` at 5,683 lines with ~60 exported functions and module-level mutable state is the highest blast-radius file in the repo, and the Rust port is a live second implementation of the compiler that must stay snapshot-identical to the TypeScript one.

All 17 risk map claims →

Extension points

The repo's main extension mechanism is the host-config pattern: write a `ReactFiberConfig.<renderer>.js`, register the renderer in `scripts/shared/inlinedHostConfigs.js` and add a fork rule, and you get a new React renderer sharing the reconciler unchanged. Bundles are similarly table-driven — add an entry to `scripts/rollup/bundles.js` and a version to `ReactVersions.js` and the build/publish pipeline picks it up. Inside the compiler, the pass list in `Pipeline.ts` / `pipeline.rs` is the ordered registry, `HIR/Globals.ts` is where hook aliasing signatures are declared, and `Environment.ts` is where feature flags live. For tooling, the ESLint plugin merges rules from a `allRules` map, the MCP servers register tools with `server.tool(name, description, schema, handler)`, and Jest behaviour is extended via `@gate` flags declared in `TestFlags.js`.

All 15 extension points claims →

Contributor handoff

Treat `/compiler/` and everything else as two separate projects with separate package managers, lockfiles, CI workflows and conventions — the root `CLAUDE.md` says so explicitly, and `compiler/CLAUDE.md` even documents Sapling (`sl`) rather than git for that subtree. Never run `jest` or `rollup` directly; use `yarn test` / `yarn flow` / `yarn linc` / `yarn prettier`, and let CI do builds. The single most important structural fact to internalise before editing is the fork/shim system: `ReactFiberConfig`, `ReactFeatureFlags` and the flight/fizz configs resolve differently under Rollup, Jest and Flow, so 'it works in one channel' is not a signal. Read the work loop, the root scheduler and the feature-flag file before touching reconciler behaviour, and read the relevant `docs/passes/` doc before touching a compiler pass.

All 15 contributor handoff claims →

Languages

LanguageFilesShare of source
JavaScript391585%
Markdown2011docs/config
TypeScript54312%
JSON153docs/config
Rust1213%
CSS108docs/config
HTML79docs/config
YAML31docs/config

Start reading here

Probable source entrypoint: packages/ — inferred from the directory tree and manifest, not the upstream docs.

Source roots

packages/ (1610 files)

Repository structure

Top-level pathFiles
compiler/1611
packages/1610
fixtures/505
scripts/195
.github/32
flow-typed/11
.claude/9
.codesandbox/1

Docs found: CLAUDE.mdCONTRIBUTING.mdREADME.md

Package

package.json — , 80 declared dependencies.

@babel/cli@babel/code-frame@babel/core@babel/helper-define-map@babel/helper-module-imports@babel/parser@babel/plugin-external-helpers@babel/plugin-proposal-class-properties@babel/plugin-proposal-object-rest-spread@babel/plugin-syntax-dynamic-import@babel/plugin-syntax-import-meta@babel/plugin-syntax-jsx

CI & config entrypoints

Structural health signals

Average score 5.4/10 across 96 analyzed source files; 92 hotspots surfaced.

These are deterministic review leads — size, churn, and structural signals — not proof of a bug in this project.

Recent history