AGENTS.md
packages/react-native-compatibility-check/AGENTS.mdAGENTS.md
Quality
99/100
Scores the file, not the repository.Length
991 words
26 headings · 3 code blocksRepository
126k
— · pushed 0 days agoLast changed
3 days ago
First indexed 3 days ago.1# AGENTS.md23This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.45## Overview67This 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) updates10- Server Components with React Native1112The tool operates on JSON schema files generated by `@react-native/codegen`, making it agnostic to TypeScript/Flow.1314## Architecture: Three-Stage Pipeline1516The compatibility check flows through three distinct stages:1718```19Schema (new) ──┐20 ├──▶ TypeDiffing ──▶ VersionDiffing ──▶ ErrorFormatting ──▶ Output21Schema (old) ──┘22```2324### 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 here2930### 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 flow36- 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**4142### Stage 3: ErrorFormatting (`ErrorFormatting.js`)43**Human-readable output** - Converts deep error objects into formatted strings.44- **Must remain pure** - no business logic4546### Supporting Files4748- **`ComparisonResult.js`**: Type definitions for all comparison result shapes49- **`DiffResults.js`**: Type definitions for schema diff results, error codes, and summary types50- **`SortTypeAnnotations.js`**: Sorting utilities for comparing type annotations in a stable order51- **`convertPropToBasicTypes.js`**: Converts Component prop types to standard type annotations for comparison52- **`index.js`**: Public API - exports `compareSchemas()` returning a `CompatCheckResult`5354## Key Type Definitions5556```javascript57// Main comparison statuses58type ComparisonResult =59 | {status: 'matching'} // Types are identical60 | {status: 'skipped'} // No old type to compare61 | {status: 'properties', ...} // Object property changes62 | {status: 'members', ...} // Enum member changes63 | {status: 'unionMembers', ...} // Union member changes64 | {status: 'functionChange', ...}// Function signature changes65 | {status: 'error', ...} // Incompatible type change6667// Summary statuses68type DiffSummary = {69 status: 'ok' | 'patchable' | 'incompatible',70 incompatibilityReport: {...}71}72```7374## Commands7576Run tests from the react-native-compatibility-check directory:77```bash78cd packages/react-native-compatibility-check7980# Run all tests81yarn test8283# Run a specific test file84yarn test src/__tests__/TypeDiffing-test.js8586# Run tests matching a pattern87yarn test --testNamePattern="compareTypes on unions"88```8990**Meta employees**: Use `js1 test SUBPATH` instead (e.g., `js1 test react-native-compatibility-check`).9192## Testing Patterns9394### Test Fixtures95Tests 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`9899The `getTestSchema()` utility parses these fixtures into schema objects.100101### Test Structure102- **TypeDiffing-test.js**: Tests pure type comparison logic103- **VersionDiffing-test.js**: Tests safety analysis with boundary direction104- **ErrorFormatting-test.js**: Tests error message generation (uses snapshots)105106### Adding Test Cases1071. Create a new fixture directory under `__tests__/__fixtures__/`1082. Add a `.js.flow` file defining a Native Module or Component1093. Load it in tests using `getTestSchema(__dirname, '__fixtures__', 'fixture-name', 'FileName.js.flow')`110111## Design Principles112113### Separation of Concerns114- **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.117118### Module-scope Type Registries119`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.120121### Structural Type Comparison122Types are compared structurally, not nominally. Two different type aliases with identical structure are considered matching.123124## Compatibility Rules Reference125126### 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 | ✅ |137138### 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 | ❌ |149150## Common Gotchas1511521. **Component Commands**: Adding/removing commands is intentionally allowed even though it could cause OTA issues, because there's no feature detection mechanism for commands.1531542. **Union ordering**: Unions are sorted before comparison, so `'a' | 'b'` equals `'b' | 'a'`.1551563. **Nullable vs Optional**: These are distinct concepts:157 - Optional: Property may be absent (`prop?: T`)158 - Nullable: Value may be null/undefined (`prop: ?T`)1591604. **Type Aliases**: Resolved during comparison. Different alias names with identical structure are treated as matching.1611625. **Component Props with Defaults**: `WithDefault` types are stripped during comparison - only the underlying type matters for compatibility.1631646. **Int32EnumTypeAnnotation**: Currently converted to `AnyTypeAnnotation` because the tool lacks support for number literal unions.165166## Adding New Type Support1671681. 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 type1725. If it affects safety analysis, update `VersionDiffing.js` checks173174## Code Style175176- All source files use `@flow strict-local` or `@flow strict`177- All source files require `@format` pragma for Prettier178- Tests use `@noflow` or `@flow` (not strict)179
Similar configs
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| TryGhost/Ghoste2e/AGENTS.md · 55k | AGENTS.md | setupteststylearch+2 | 100/100 | 3 days ago | |
| code-yeongyu/oh-my-openagentpackages/web/AGENTS.md · 67k | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 2 days ago | |
| mui/material-uiAGENTS.md · 99k | AGENTS.md | setupbuildtestlint-format+9 | 100/100 | 3 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-frontend/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+6 | 100/100 | 2 days ago | |
| unoplat/unoplat-code-confluenceunoplat-code-confluence-query-engine/AGENTS.md · 95 | AGENTS.md | setupbuildtestlint-format+5 | 98/100 | 2 days ago | |
| hashintel/hashlibs/@hashintel/ds-components/AGENTS.md · 1.6k | AGENTS.md | buildtestlint-formatstyle+5 | 97/100 | 3 days ago | |
| JCodesMore/ai-website-cloner-templateAGENTS.md · 31k | AGENTS.md | buildlint-formatstylearch+1 | 97/100 | 2 days ago | |
| alibaba/opc-starterAGENTS.md · 87 | AGENTS.md | setupbuildtestlint-format+5 | 97/100 | 3 days ago |
