Monorepo & Build System
Monorepo Architecture
React is managed as a monorepo containing several interdependent packages. This structure allows the core team to coordinate changes across the reconciler, the renderers (DOM, Native, Server), and the compiler simultaneously.
Package Structure
The repository is organized under the packages/ directory. Each package is a self-contained unit with its own package.json, though they share a unified build and testing infrastructure.
react: The core API (e.g.,useState,useMemo,Component).react-dom: The entry point for web-based rendering.react-reconciler: The host-independent algorithm used to manage the React tree and diffing logic.compiler/: Contains the React Compiler (Babel plugin), organized into its own sub-monorepo.babel-plugin-react-compiler: The primary transformation engine.react-compiler-healthcheck: Tooling to validate project compatibility.
Build System: Rollup and CI
The build system leverages Rollup for bundling and Babel for transpilation. The pipeline is designed to produce multiple build artifacts optimized for different environments (development vs. production) and module systems (CommonJS, ESM, and UMD).
Build Process Flow
- Source Transformation: TypeScript and Flow sources are transpiled via Babel.
- Internal Inlining: Optimization passes inline feature flags and environment-specific constants (e.g.,
__DEV__). - Bundling: Rollup generates the final artifacts.
- Validation: Post-build scripts verify the integrity of the bundles, ensuring no internal-only APIs are leaked to the public interface.
To build the project locally:
# Install dependencies
yarn
# Build all packages
yarn build
# Build specific packages (e.g., react and react-dom)
yarn build react,react-dom --type=NODE
Release Channels
React uses a multi-channel release strategy to balance stability for production apps with early access to new features for the ecosystem.
| Channel | Purpose | Stability | | :--- | :--- | :--- | | Latest (Stable) | General production use. Follows semver. | High | | Canary | Features that are expected to land in the next minor/major. Used by frameworks like Next.js. | Moderate | | Experimental | Research and development (e.g., upcoming concurrent features). APIs may change without notice. | Low |
Canary Releases
Unlike traditional "beta" versions, React Canaries are intended to be stable enough for production if used within a managed framework. This allows React to ship features like Server Components and Actions which require tight integration between the library and the bundler.
React Compiler (Babel Plugin)
The React Compiler is a significant addition to the build pipeline. It functions as a Babel plugin that transforms standard React code into highly optimized code that automatically manages memoization.
Internal Logic: Escape Analysis
The compiler performs complex static analysis to determine which values need to be memoized. A core component of this is Escape Analysis, implemented in passes such as pruneNonEscapingScopes.ts.
The compiler builds a graph of IdentifierId nodes to track:
- Direct Escapes: Values returned by a function or transitively aliased by a return value.
- Indirect Escapes: Values passed to hooks (e.g.,
useEffectdependencies), which React might store internally.
/*
Example of Compiler Logic:
The compiler identifies that 'a' does not escape,
but it must be memoized because 'b' (which does escape)
depends on it.
*/
function Component(props) {
const a = [props.a]; // Non-escaping
const b = [a]; // Escaping (via return)
return b;
}
Validation Passes
The build system includes strict validation to ensure the compiler doesn't break React's rules. For example, ValidateNoCapitalizedCalls.ts prevents the invocation of capitalized functions (which look like components) as regular functions, enforcing the use of JSX for component rendering.
// Internal Validation Error Example
const reason = 'Capitalized functions are reserved for components, which must be invoked with JSX.';
// If the compiler detects: const x = SomeComponent();
// It throws a CompilerError.
Developer Workflow
Testing
React uses a custom testing harness built on Jest to handle the nuances of concurrent rendering and the compiler.
- Unit Tests: Located in
__tests__directories within each package. - Fixtures: The compiler uses a fixture-based testing system (
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures) where input JS files are compared against expected output HIR (High-level Intermediate Representation).
To run tests:
# Run all tests
yarn test
# Run compiler specific tests
yarn jest compiler
Linting and Typing
The monorepo enforces strict coding standards via ESLint and uses a mix of Flow and TypeScript. New infrastructure, specifically the React Compiler, is written primarily in TypeScript to leverage its robust ecosystem of static analysis tools.