AGENTS.md in react/react-native runs 991 words across 26 headings.
A framework for building native applications using React
Covers
8 of the 20 section tags
In the order a file is read inHeadings
26 headings, in the order the file writes them
01AGENTS.md
02Overview
03Architecture: Three-Stage Pipeline
04Stage 1: TypeDiffing (`TypeDiffing.js`)
05Stage 2: VersionDiffing (`VersionDiffing.js`)
06Stage 3: ErrorFormatting (`ErrorFormatting.js`)
07Supporting Files
08Key Type Definitions
09Commands
10Run all tests
11Run a specific test file
12Run tests matching a pattern
13Testing Patterns
14Test Fixtures
15Test Structure
16Adding Test Cases
17Design Principles
18Separation of Concerns
19Module-scope Type Registries
20Structural Type Comparison
21Compatibility Rules Reference
22Data Flowing TO Native (parameters, props)
23Data Flowing FROM Native (return values, constants)
24Common Gotchas
25Adding New Type Support
26Code Style
Commands
3 commands this file writes down
Extracted from the file, verbatimyarn test
yarn test src/__tests__/TypeDiffing-test.js
yarn test --testNamePattern="compareTypes on unions"
The file
packages/react-native-compatibility-check/AGENTS.md
First 160 of 179 lines1# AGENTS.md
2
3This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
5## Overview
6
7This package is a **type checker for React Native's JS/Native boundary**. It detects backwards-incompatible changes between JavaScript and Native code to prevent crashes, particularly useful for:
8- Local development (detecting when native rebuild is needed)
9- Over-the-air (OTA) updates
10- Server Components with React Native
11
12The tool operates on JSON schema files generated by `@react-native/codegen`, making it agnostic to TypeScript/Flow.
13
14## Architecture: Three-Stage Pipeline
15
16The compatibility check flows through three distinct stages:
17
18```
19Schema (new) ──┐
20 ├──▶ TypeDiffing ──▶ VersionDiffing ──▶ ErrorFormatting ──▶ Output
21Schema (old) ──┘
22```
23
24### Stage 1: TypeDiffing (`TypeDiffing.js`)
25**Pure type comparison** - Compares two type annotations and returns all structural differences.
26- Reports ALL differences between types (added/removed properties, union changes, etc.)
27- Returns `ComparisonResult` with status: `matching`, `skipped`, `properties`, `members`, `unionMembers`, `functionChange`, `positionalTypeChange`, `nullableChange`, or `error`
28- **Must remain pure** - no React Native-specific logic belongs here
29
30### Stage 2: VersionDiffing (`VersionDiffing.js`)
31**Semantic safety analysis** - Interprets TypeDiffing results in the context of React Native's boundary.
32- Determines if changes are safe based on **data flow direction**:
33 - `toNative`: Data flows from JS to Native (method parameters, component props)
34 - `fromNative`: Data flows from Native to JS (return values, getConstants)
35 - `both`: Bidirectional flow
36- Encodes compatibility rules:
37 - Adding to a union sent TO native = **UNSAFE** (native won't expect it)
38 - Removing from a union received FROM native = **UNSAFE** (JS won't handle it)
39 - Adding optional properties = **SAFE**
40 - Making required properties optional when sending TO native = **UNSAFE**
41
42### Stage 3: ErrorFormatting (`ErrorFormatting.js`)
43**Human-readable output** - Converts deep error objects into formatted strings.
44- **Must remain pure** - no business logic
45
46### Supporting Files
47
48- **`ComparisonResult.js`**: Type definitions for all comparison result shapes
49- **`DiffResults.js`**: Type definitions for schema diff results, error codes, and summary types
50- **`SortTypeAnnotations.js`**: Sorting utilities for comparing type annotations in a stable order
51- **`convertPropToBasicTypes.js`**: Converts Component prop types to standard type annotations for comparison
52- **`index.js`**: Public API - exports `compareSchemas()` returning a `CompatCheckResult`
53
54## Key Type Definitions
55
56```javascript
57// Main comparison statuses
58type ComparisonResult =
59 | {status: 'matching'} // Types are identical
60 | {status: 'skipped'} // No old type to compare
61 | {status: 'properties', ...} // Object property changes
62 | {status: 'members', ...} // Enum member changes
63 | {status: 'unionMembers', ...} // Union member changes
64 | {status: 'functionChange', ...}// Function signature changes
65 | {status: 'error', ...} // Incompatible type change
66
67// Summary statuses
68type DiffSummary = {
69 status: 'ok' | 'patchable' | 'incompatible',
70 incompatibilityReport: {...}
71}
72```
73
74## Commands
75
76Run tests from the react-native-compatibility-check directory:
77```bash
78cd packages/react-native-compatibility-check
79
80# Run all tests
81yarn test
82
83# Run a specific test file
84yarn test src/__tests__/TypeDiffing-test.js
85
86# Run tests matching a pattern
87yarn test --testNamePattern="compareTypes on unions"
88```
89
90**Meta employees**: Use `js1 test SUBPATH` instead (e.g., `js1 test react-native-compatibility-check`).
91
92## Testing Patterns
93
94### Test Fixtures
95Tests use Flow files in `__tests__/__fixtures__/` parsed by `@react-native/codegen`:
96- **Native Modules**: `native-module-*/NativeModule.js.flow`
97- **Native Components**: `native-component-*/NativeComponent.js.flow`
98
99The `getTestSchema()` utility parses these fixtures into schema objects.
100
101### Test Structure
102- **TypeDiffing-test.js**: Tests pure type comparison logic
103- **VersionDiffing-test.js**: Tests safety analysis with boundary direction
104- **ErrorFormatting-test.js**: Tests error message generation (uses snapshots)
105
106### Adding Test Cases
1071. Create a new fixture directory under `__tests__/__fixtures__/`
1082. Add a `.js.flow` file defining a Native Module or Component
1093. Load it in tests using `getTestSchema(__dirname, '__fixtures__', 'fixture-name', 'FileName.js.flow')`
110
111## Design Principles
112
113### Separation of Concerns
114- **TypeDiffing**: Pure type comparison. Should work for ANY JavaScript types.
115- **VersionDiffing**: React Native boundary semantics. Only place for RN-specific logic.
116- **ErrorFormatting**: Presentation only. No business logic.
117
118### Module-scope Type Registries
119`TypeDiffing.js` uses module-scope variables (`_newerTypesReg`, `_olderTypesReg`, `_newerEnumMap`, `_olderEnumMap`) to avoid threading lookups through all recursive calls. This is acceptable because the logic is serial.
120
121### Structural Type Comparison
122Types are compared structurally, not nominally. Two different type aliases with identical structure are considered matching.
123
124## Compatibility Rules Reference
125
126### Data Flowing TO Native (parameters, props)
127| Change | Safe? |
128|--------|-------|
129| Add optional property | ✅ |
130| Add required property | ❌ |
131| Remove property | ✅ |
132| Make property optional | ❌ |
133| Add union member | ❌ |
134| Remove union member | ✅ |
135| Add enum member | ❌ |
136| Remove enum member | ✅ |
137
138### Data Flowing FROM Native (return values, constants)
139| Change | Safe? |
140|--------|-------|
141| Add optional property | ✅ |
142| Add required property | ❌ |
143| Remove property | ✅ |
144| Make property required | ❌ |
145| Add union member | ✅ |
146| Remove union member | ❌ |
147| Add enum member | ✅ |
148| Remove enum member | ❌ |
149
150## Common Gotchas
151
1521. **Component Commands**: Adding/removing commands is intentionally allowed even though it could cause OTA issues, because there's no feature detection mechanism for commands.
153
1542. **Union ordering**: Unions are sorted before comparison, so `'a' | 'b'` equals `'b' | 'a'`.
155
1563. **Nullable vs Optional**: These are distinct concepts:
157 - Optional: Property may be absent (`prop?: T`)
158 - Nullable: Value may be null/undefined (`prop: ?T`)
159
1604. **Type Aliases**: Resolved during comparison. Different alias names with identical structure are treated as matching.
19 more lines are in the file. Read the raw file.
The rest of the repository
react/react-native ships 1 other instruction files
This listing
Whoever runs react/react-native can claim it
This is yours? Claim this config and we will write to you when the measurement moves. The check is one token placed where only you can place it, and there is no account and no password.