Technical Contribution Guide
Codebase Architecture and Monorepo Structure
The React repository is managed as a monorepo. While the core library resides in packages/react, significant logic—including the React Compiler (Babel plugin)—is located under compiler/packages/.
When contributing to the compiler, you will primarily interact with the following directories:
src/HIR: Defines the High-level Intermediate Representation, the core data structure used for optimization passes.src/ReactiveScopes: Contains logic for grouping instructions into memoization blocks (e.g.,PruneNonEscapingScopes.ts).src/Validation: Implements static analysis rules to ensure code adheres to React's rules (e.g.,ValidateNoCapitalizedCalls.ts).
Development Standards and Internal Linting
React employs strict internal linting and validation passes that go beyond standard ESLint configurations. These are implemented as compiler passes to ensure the stability of the generated code.
1. Function and Method Invocations
The compiler enforces specific naming conventions for function calls to distinguish between standard logic and React Components.
- Capitalized Calls: Functions starting with an uppercase letter are reserved for components. They must be invoked via JSX, not as direct function calls.
- Allow-lists: Global objects (e.g.,
Boolean,Number,String) and hooks (defined byenvConfig.hookPattern) are exempt from this check. - Internal Validation:
ValidateNoCapitalizedCalls.tsscansLoadGlobal,CallExpression, andMethodCallinstructions to catch invalid patterns:// Invalid: Capitalized function call const x = SomeFunc(); // Valid: JSX invocation const x = <SomeFunc />;
2. Escape Analysis and Memoization
When contributing to optimization passes, you must account for "escaping" values. A value is considered to escape if:
- It is directly returned by a function.
- It is transitively aliased by a return value.
- It is passed as an argument to a hook (as hooks may store references externally).
The PruneNonEscapingScopes pass removes reactive scopes that do not contribute to an escaping value. However, a scope must be preserved if it produces a dependency for another memoized output, even if that specific dependency doesn't escape.
Contribution Workflow
Signing Commits
All contributors must sign the Meta Contributor License Agreement (CLA) before pull requests can be merged. Ensure your local git configuration matches the email used for the CLA.
Working with Fixtures
React uses a fixture-based testing system for the compiler. If you are modifying compiler logic, you must add or update fixtures in src/__tests__/fixtures/compiler.
- Test Metadata: Fixtures use special headers to configure the environment:
@validateNoCapitalizedCalls: Enables the capitalized call check.@compilationMode:"infer": Opts into automatic inference.@expectNothingCompiled: Asserts that the compiler should skip this file.
Internal Logic Flow
If you are implementing a new transformation, extend the ReactiveFunctionTransform or ReactiveFunctionVisitor classes. These provide a structured way to traverse the Reactive Function tree:
import { ReactiveFunctionVisitor, visitReactiveFunction } from './visitors';
class MyCustomPass extends ReactiveFunctionVisitor<void> {
override visitInstruction(instruction: ReactiveInstruction): void {
// Implement logic for specific instruction types
}
}
export function myCustomPass(fn: ReactiveFunction): void {
const state = new MyCustomPass();
visitReactiveFunction(fn, state, undefined);
}
Static Analysis and Error Handling
React utilizes a custom CompilerError class for reporting issues during the build process. When implementing validation:
- Use
ErrorCategoryto classify the issue (e.g.,ErrorCategory.CapitalizedCalls). - Provide a
reasonthat explains the React-specific rule being violated. - Include the
loc(location) from the HIR instruction to ensure accurate source maps in error messages.