-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmobile-native-compat.mdc
More file actions
131 lines (99 loc) · 4.12 KB
/
mobile-native-compat.mdc
File metadata and controls
131 lines (99 loc) · 4.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
---
description: Flag deprecated native APIs, bridge-only module patterns, and New Architecture incompatibilities
globs: ["*.ts", "*.tsx", "*.dart"]
alwaysApply: false
standards-version: 1.6.3
---
# Native Compatibility
## Purpose
Detect usage of deprecated native APIs, bridge-only patterns incompatible with the New Architecture (Fabric/TurboModules), and sunset React Native APIs that have modern replacements.
## Flagged Patterns
### 1. Legacy NativeModules Bridge (React Native)
```tsx
// ❌ Old bridge pattern - not compatible with New Architecture
import { NativeModules } from "react-native";
const { MyModule } = NativeModules;
// ✅ Turbo Module via Expo Modules API
import MyModule from "./MyModule";
// ✅ Turbo Module via TurboModuleRegistry
import { TurboModuleRegistry } from "react-native";
const MyModule = TurboModuleRegistry.getEnforcing("MyModule");
```
### 2. Deprecated requireNativeComponent
```tsx
// ❌ Legacy view manager - bridge-only
import { requireNativeComponent } from "react-native";
const MyView = requireNativeComponent("MyNativeView");
// ✅ Expo view component
import { requireNativeViewManager } from "expo-modules-core";
const MyView = requireNativeViewManager("MyNativeView");
```
### 3. UIManager Direct Access
```tsx
// ❌ UIManager is bridge-only and partially removed in New Architecture
import { UIManager } from "react-native";
UIManager.dispatchViewManagerCommand(viewRef, "focus", []);
// ✅ Use refs and component methods
viewRef.current?.focus();
```
### 4. NativeEventEmitter Without Listener Count
```tsx
// ❌ Missing required addListener/removeListeners spec (RN 0.73+)
const emitter = new NativeEventEmitter(NativeModules.MyModule);
// ✅ Module must implement addListener and removeListeners
// In the Turbo Module spec:
export interface Spec extends TurboModule {
addListener(eventType: string): void;
removeListeners(count: number): void;
}
```
### 5. Deprecated React Native APIs
Flag usage of APIs removed or deprecated in recent React Native versions:
- `ViewPropTypes` - removed in RN 0.71+; use TypeScript props instead
- `ColorPropType` - removed; use TypeScript types
- `EdgeInsetsPropType` - removed; use TypeScript types
- `PointPropType` - removed; use TypeScript types
- `BackAndroid` - removed; use `BackHandler`
- `NetInfo` from `react-native` - use `@react-native-community/netinfo`
- `AsyncStorage` from `react-native` - use `@react-native-async-storage/async-storage`
- `ImageEditor` from `react-native` - use `@react-native-community/image-editor`
### 6. Flutter Deprecated APIs
```dart
// ❌ Deprecated in Flutter 3.x
FlatButton(onPressed: () {}, child: Text("OK"))
RaisedButton(onPressed: () {}, child: Text("OK"))
// ✅ Modern replacements
TextButton(onPressed: () {}, child: Text("OK"))
ElevatedButton(onPressed: () {}, child: Text("OK"))
```
```dart
// ❌ Deprecated color access
Theme.of(context).accentColor
Theme.of(context).backgroundColor
// ✅ ColorScheme access
Theme.of(context).colorScheme.secondary
Theme.of(context).colorScheme.surface
```
### 7. Platform-Specific API Without Version Check
```kotlin
// ❌ Using API without version check
val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
vibrator.vibrate(100) // Deprecated in API 26
// ✅ With version check
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
vibrator.vibrate(VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE))
} else {
@Suppress("DEPRECATION")
vibrator.vibrate(100)
}
```
## Exceptions
- Code inside migration/compatibility layers that intentionally supports both old and new APIs
- Test files that mock legacy modules for backward compatibility testing
- Config plugin code that reads legacy format and converts to new format
- Polyfill files explicitly documented as bridge compatibility shims
## Resources
- [React Native New Architecture](https://reactnative.dev/docs/the-new-architecture/landing-page)
- [Expo Modules API](https://docs.expo.dev/modules/overview/)
- [Flutter Deprecation Policy](https://docs.flutter.dev/release/compatibility-policy)
- [React Native Upgrade Helper](https://react-native-community.github.io/upgrade-helper/)