Two files, one repository
react/react-native ships 1 format across 2 indexed files. The question worth asking is whether the second one says anything the first does not.
| Dimension | Shared | Only in A | Only in B | Overlap |
|---|---|---|---|---|
| Sections | 0 | 5 | 26 | 0% |
| Commands | 0 | 9 | 3 | 0% |
| Section tags | 3 | 1 | 5 | 33% |
What each file covers
Sections
0 shared · 5 only in A · 26 only in B- − React Native
- − Repo structure
- − Common commands
- − Gotchas
- − Contributing guidelines
- + AGENTS.md
- + Overview
- + Architecture: Three-Stage Pipeline
- + Stage 1: TypeDiffing (`TypeDiffing.js`)
- + Stage 2: VersionDiffing (`VersionDiffing.js`)
- + Stage 3: ErrorFormatting (`ErrorFormatting.js`)
- + Supporting Files
- + Key Type Definitions
- + Commands
- + Run all tests
- + Run a specific test file
- + Run tests matching a pattern
- + Testing Patterns
- + Test Fixtures
- + Test Structure
- + Adding Test Cases
- + Design Principles
- + Separation of Concerns
- + Module-scope Type Registries
- + Structural Type Comparison
- + Compatibility Rules Reference
- + Data Flowing TO Native (parameters, props)
- + Data Flowing FROM Native (return values, constants)
- + Common Gotchas
- + Adding New Type Support
- + Code Style
Commands
0 shared · 9 only in A · 3 only in B- − yarn test <path>
- − yarn fantom <path>
- − yarn lint
- − yarn format
- − yarn flow-check
- − yarn start
- − yarn android
- − yarn build-types
- − yarn cxx-api-build
- + yarn test
- + yarn test src/__tests__/TypeDiffing-test.js
- + yarn test --testNamePattern="compareTypes on unions"
Section tags
3 shared · 1 only in A · 5 only in B- − git-pr
- + code-style
- + types
- + testing-strategy
- + deployment
- + do-not
- test
- lint-format
- architecture
Line diff
react/react-native · AGENTS.md
@@ −1 @@
1# React Native
2
3A framework for building native applications using React.
4
5This file provides guidance for coding agents working in this repository.
6
7## Repo structure
8
9React Native is a monorepo: the `react-native` package, the packages published alongside it, and the apps and tooling used to develop them.
10
11| Path | Contents |
12| --- | --- |
13| `packages/react-native/Libraries` | JavaScript source (Flow) — the legacy location, with code gradually moving to `src/private` |
14| `packages/react-native/src/private` | JavaScript source (Flow) |
15| `packages/react-native/ReactCommon` | Shared C++ — Fabric renderer, TurboModules, JSI, Yoga, `jsinspector-modern` |
16| `packages/react-native/ReactAndroid` | Android runtime (Kotlin, Java, JNI) |
17| `packages/react-native/{React,ReactApple}` | Apple runtime (Objective-C++, Swift) |
18| `packages/rn-tester` | RNTester — test app showcasing each core component and API, plus a `Playground` scratch surface |
19| `packages/*` | Other published packages — Metro config, Codegen, ESLint config, dev-middleware, React Native DevTools frontend |
20| `private/*` | Unpublished — the `helloworld` sample app, the `react-native-fantom` test runner |
21| `scripts/*` | Repository tooling — build, test, release, and CI scripts |
22
23Architecture notes live in `__docs__` directories beside the code they describe, indexed by [`__docs__/README.md`](__docs__/README.md). Treat them as reference for the subsystem you are working in, not as required reading.
24
25## Common commands
26
27Run these from the repository root:
28
29| Command | Purpose |
30| --- | --- |
31| `yarn test <path>` | Jest unit tests, found in `__tests__` directories |
32| `yarn fantom <path>` | [Fantom](private/react-native-fantom/__docs__/README.md) integration tests, named `*-itest.js` |
33| `yarn lint` | ESLint |
34| `yarn format` | Prettier and clang-format |
35| `yarn flow-check` | Flow |
36| `yarn start`, `yarn android` | Metro, and RNTester on Android. See [RNTester](packages/rn-tester/README.md) for iOS |
37
38Native builds use Gradle on Android, and CocoaPods or Swift Package Manager on iOS. See [Building from source](https://reactnative.dev/contributing/how-to-build-from-source).
39
40## Gotchas
41
42- JavaScript sources are typed with Flow, and the public API is exported from `packages/react-native/index.js`. TypeScript types are generated from those sources, and `packages/react-native/ReactNativeApi.d.ts` is a committed snapshot of that API — run `yarn build-types` to regenerate both whenever the public API changes.
43- The public native API is snapshotted as well: C++ under `scripts/cxx-api` (`yarn cxx-api-build`), and Android in `packages/react-native/ReactAndroid/api/ReactAndroid.api`. CI validates both.
44- Native modules and components are declared by JavaScript specs (`Native*.js`, `*NativeComponent.js`), from which their native counterparts are generated. Do not hand-edit generated code.
45- `CHANGELOG.md` is compiled at release time. Changelog entries belong in the pull request description.
46
47## Contributing guidelines
48
49- Keep each change focused — no unrelated refactors, formatting, or dependency updates.
50- Complete the pull request template — the motivation and the user-visible effect, and a [changelog entry](https://reactnative.dev/contributing/changelogs-in-pull-requests) with its category and type tags.
51- In the test plan, give the exact commands you ran and their results, plus screenshots or a video for user-interface changes.
52
53See [CONTRIBUTING.md](CONTRIBUTING.md) for the full process, including how to report bugs.
54
react/react-native · packages/react-native-compatibility-check/AGENTS.md
@@ +1 @@
1# 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.
161
1625. **Component Props with Defaults**: `WithDefault` types are stripped during comparison - only the underlying type matters for compatibility.
163
1646. **Int32EnumTypeAnnotation**: Currently converted to `AnyTypeAnnotation` because the tool lacks support for number literal unions.
165
166## Adding New Type Support
167
1681. Add the type case to `compareTypeAnnotation()` in `TypeDiffing.js`
1692. Add sorting logic in `SortTypeAnnotations.js` (`compareTypeAnnotationForSorting`)
1703. Add formatting in `ErrorFormatting.js` (`formatTypeAnnotation`)
1714. Add test fixtures and tests covering the new type
1725. If it affects safety analysis, update `VersionDiffing.js` checks
173
174## Code Style
175
176- All source files use `@flow strict-local` or `@flow strict`
177- All source files require `@format` pragma for Prettier
178- Tests use `@noflow` or `@flow` (not strict)
179
@@ −1 +1 @@
1−# React Native
1+# AGENTS.md
22
3−A framework for building native applications using React.
3+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
44
5−This file provides guidance for coding agents working in this repository.
5+## Overview
66
7−## Repo structure
7+This 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
811
9−React Native is a monorepo: the `react-native` package, the packages published alongside it, and the apps and tooling used to develop them.
12+The tool operates on JSON schema files generated by `@react-native/codegen`, making it agnostic to TypeScript/Flow.
1013
11−| Path | Contents |
12−| --- | --- |
13−| `packages/react-native/Libraries` | JavaScript source (Flow) — the legacy location, with code gradually moving to `src/private` |
14−| `packages/react-native/src/private` | JavaScript source (Flow) |
15−| `packages/react-native/ReactCommon` | Shared C++ — Fabric renderer, TurboModules, JSI, Yoga, `jsinspector-modern` |
16−| `packages/react-native/ReactAndroid` | Android runtime (Kotlin, Java, JNI) |
17−| `packages/react-native/{React,ReactApple}` | Apple runtime (Objective-C++, Swift) |
18−| `packages/rn-tester` | RNTester — test app showcasing each core component and API, plus a `Playground` scratch surface |
19−| `packages/*` | Other published packages — Metro config, Codegen, ESLint config, dev-middleware, React Native DevTools frontend |
20−| `private/*` | Unpublished — the `helloworld` sample app, the `react-native-fantom` test runner |
21−| `scripts/*` | Repository tooling — build, test, release, and CI scripts |
14+## Architecture: Three-Stage Pipeline
2215
23−Architecture notes live in `__docs__` directories beside the code they describe, indexed by [`__docs__/README.md`](__docs__/README.md). Treat them as reference for the subsystem you are working in, not as required reading.
16+The compatibility check flows through three distinct stages:
2417
25−## Common commands
18+```
19+Schema (new) ──┐
20+ ├──▶ TypeDiffing ──▶ VersionDiffing ──▶ ErrorFormatting ──▶ Output
21+Schema (old) ──┘
22+```
2623
27−Run these from the repository root:
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
2829
29−| Command | Purpose |
30−| --- | --- |
31−| `yarn test <path>` | Jest unit tests, found in `__tests__` directories |
32−| `yarn fantom <path>` | [Fantom](private/react-native-fantom/__docs__/README.md) integration tests, named `*-itest.js` |
33−| `yarn lint` | ESLint |
34−| `yarn format` | Prettier and clang-format |
35−| `yarn flow-check` | Flow |
36−| `yarn start`, `yarn android` | Metro, and RNTester on Android. See [RNTester](packages/rn-tester/README.md) for iOS |
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**
3741
38−Native builds use Gradle on Android, and CocoaPods or Swift Package Manager on iOS. See [Building from source](https://reactnative.dev/contributing/how-to-build-from-source).
42+### Stage 3: ErrorFormatting (`ErrorFormatting.js`)
43+**Human-readable output** - Converts deep error objects into formatted strings.
44+- **Must remain pure** - no business logic
3945
40−## Gotchas
46+### Supporting Files
4147
42−- JavaScript sources are typed with Flow, and the public API is exported from `packages/react-native/index.js`. TypeScript types are generated from those sources, and `packages/react-native/ReactNativeApi.d.ts` is a committed snapshot of that API — run `yarn build-types` to regenerate both whenever the public API changes.
43−- The public native API is snapshotted as well: C++ under `scripts/cxx-api` (`yarn cxx-api-build`), and Android in `packages/react-native/ReactAndroid/api/ReactAndroid.api`. CI validates both.
44−- Native modules and components are declared by JavaScript specs (`Native*.js`, `*NativeComponent.js`), from which their native counterparts are generated. Do not hand-edit generated code.
45−- `CHANGELOG.md` is compiled at release time. Changelog entries belong in the pull request description.
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`
4653
47−## Contributing guidelines
54+## Key Type Definitions
4855
49−- Keep each change focused — no unrelated refactors, formatting, or dependency updates.
50−- Complete the pull request template — the motivation and the user-visible effect, and a [changelog entry](https://reactnative.dev/contributing/changelogs-in-pull-requests) with its category and type tags.
51−- In the test plan, give the exact commands you ran and their results, plus screenshots or a video for user-interface changes.
56+```javascript
57+// Main comparison statuses
58+type 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
5266
53−See [CONTRIBUTING.md](CONTRIBUTING.md) for the full process, including how to report bugs.
67+// Summary statuses
68+type DiffSummary = {
69+ status: 'ok' | 'patchable' | 'incompatible',
70+ incompatibilityReport: {...}
71+}
72+```
73+
74+## Commands
75+
76+Run tests from the react-native-compatibility-check directory:
77+```bash
78+cd packages/react-native-compatibility-check
79+
80+# Run all tests
81+yarn test
82+
83+# Run a specific test file
84+yarn test src/__tests__/TypeDiffing-test.js
85+
86+# Run tests matching a pattern
87+yarn 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
95+Tests 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+
99+The `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
107+1. Create a new fixture directory under `__tests__/__fixtures__/`
108+2. Add a `.js.flow` file defining a Native Module or Component
109+3. 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
122+Types 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+
152+1. **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+
154+2. **Union ordering**: Unions are sorted before comparison, so `'a' | 'b'` equals `'b' | 'a'`.
155+
156+3. **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+
160+4. **Type Aliases**: Resolved during comparison. Different alias names with identical structure are treated as matching.
161+
162+5. **Component Props with Defaults**: `WithDefault` types are stripped during comparison - only the underlying type matters for compatibility.
163+
164+6. **Int32EnumTypeAnnotation**: Currently converted to `AnyTypeAnnotation` because the tool lacks support for number literal unions.
165+
166+## Adding New Type Support
167+
168+1. Add the type case to `compareTypeAnnotation()` in `TypeDiffing.js`
169+2. Add sorting logic in `SortTypeAnnotations.js` (`compareTypeAnnotationForSorting`)
170+3. Add formatting in `ErrorFormatting.js` (`formatTypeAnnotation`)
171+4. Add test fixtures and tests covering the new type
172+5. If it affects safety analysis, update `VersionDiffing.js` checks
173+
174+## Code Style
175+
176+- All source files use `@flow strict-local` or `@flow strict`
177+- All source files require `@format` pragma for Prettier
178+- Tests use `@noflow` or `@flow` (not strict)
54179
