Development Workflow
Prerequisites
The React Compiler is located within the compiler/ directory of the React monorepo. Before starting development, ensure you have the repository dependencies installed:
# From the root of the react repository
yarn install
Running Tests
The compiler uses a fixture-based testing system. Most tests are located in packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler.
To run the full suite of compiler tests:
yarn jest packages/babel-plugin-react-compiler
To run tests in watch mode for a faster feedback loop:
yarn jest packages/babel-plugin-react-compiler --watch
Working with Test Fixtures
The primary way to verify changes is by adding or modifying test fixtures. Each fixture is a standalone JavaScript file that represents a React component or hook.
Creating a New Fixture
- Create a new
.jsor.tsfile insrc/__tests__/fixtures/compiler. - Define a component or function.
- Export a
FIXTURE_ENTRYPOINTobject to define how the test should execute.
function Component(props) {
const x = [props.value];
return x;
}
export const FIXTURE_ENTRYPOINT = {
fn: Component,
params: [{ value: 'hello' }],
isComponent: true,
};
Fixture Configuration (Pragmas)
You can configure the compiler's behavior for a specific test using "pragmas" at the top of the file. These correspond to EnvironmentConfig settings:
| Pragma | Description |
| :--- | :--- |
| @compilationMode:"infer" | Enables the compiler to infer whether a component should be optimized. |
| @validateNoCapitalizedCalls | Enables validation that capitalized functions (potential components) are not called directly. |
| @enablePreserveExistingMemoizationGuarantees | Validates that the compiler respects existing useMemo/useCallback boundaries. |
| @expectNothingCompiled | Asserts that the compiler should skip this file. |
Verifying Compiler Errors
To test that the compiler correctly identifies and reports errors (e.g., React rule violations), create a fixture that triggers a CompilerError.
The test runner will compare the thrown error against an expected output. If you are creating a new error test, the test runner will generate a .expect.md file (or update the existing one) showing the error message and the code location.
Example of an error-triggering fixture:
// @validateNoCapitalizedCalls
function Component() {
// This should trigger a CapitalizedCalls error
const x = SomeGlobalFunction();
return x;
}
Debugging Intermediate Representations
The compiler transforms code through several stages:
- HIR (High-level Intermediate Representation): A flat, SSA-based representation.
- Reactive Function: A tree-based representation used for grouping instructions into reactive scopes.
- Javascript: The final output.
When a test fails, examine the generated output in the console or the corresponding .expect.md file. It typically includes the HIR and the final transformed JavaScript to help trace where logic may have diverged.
Validation Passes
If you are working on a new validation rule, ensure it is registered in the main compilation pipeline and verify it by adding a fixture to src/Validation. For example, ValidateNoCapitalizedCalls.ts ensures that components are rendered with JSX rather than called as functions.
Local Linking
If you need to test the compiler against a local React project:
- Build the compiler package:
cd compiler/packages/babel-plugin-react-compiler yarn build - Use
yarn linkornpm linkto point your project'sbabel-plugin-react-compilerdependency to your local build.