0
# @react-native/eslint-plugin
1
2
@react-native/eslint-plugin is an ESLint plugin that provides custom rules specifically designed for React Native development. It includes two main rules: `platform-colors` for enforcing statically analyzable PlatformColor/DynamicColorIOS calls, and `no-deep-imports` for preventing deep imports from React Native internal modules.
3
4
## Package Information
5
6
- **Package Name**: @react-native/eslint-plugin
7
- **Package Type**: npm
8
- **Language**: JavaScript
9
- **Installation**: `npm install --save-dev @react-native/eslint-plugin`
10
11
## Core Imports
12
13
```javascript
14
// ESLint plugin structure
15
const plugin = require("@react-native/eslint-plugin");
16
// plugin.rules contains: { "platform-colors": ..., "no-deep-imports": ... }
17
18
// Direct rule access
19
const platformColorsRule = require("@react-native/eslint-plugin/platform-colors");
20
const noDeepImportsRule = require("@react-native/eslint-plugin/no-deep-imports");
21
22
// Utility mapping for deep imports fix
23
const { publicAPIMapping } = require("@react-native/eslint-plugin/utils");
24
```
25
26
For ESLint configuration (`.eslintrc.json`):
27
28
```json
29
{
30
"plugins": ["@react-native"]
31
}
32
```
33
34
## Basic Usage
35
36
This plugin is designed to be used as part of `@react-native/eslint-config`, but can be configured independently:
37
38
```json
39
{
40
"plugins": ["@react-native"],
41
"rules": {
42
"@react-native/platform-colors": "error",
43
"@react-native/no-deep-imports": "error"
44
}
45
}
46
```
47
48
**Accessing the plugin programmatically:**
49
50
```javascript
51
const plugin = require("@react-native/eslint-plugin");
52
53
// Get available rules
54
console.log(Object.keys(plugin.rules)); // ["platform-colors", "no-deep-imports"]
55
56
// Access public API mapping for programmatic use
57
const { publicAPIMapping } = require("@react-native/eslint-plugin/utils");
58
console.log(publicAPIMapping["Libraries/Components/Button"]);
59
// { default: "Button", types: ["ButtonProps"] }
60
```
61
62
## Capabilities
63
64
### Plugin Rules Export
65
66
The main plugin export containing all ESLint rule definitions.
67
68
```javascript { .api }
69
/**
70
* Main plugin export with ESLint rules
71
*/
72
exports.rules = {
73
"platform-colors": require('./platform-colors'),
74
"no-deep-imports": require('./no-deep-imports')
75
};
76
```
77
78
### Platform Colors Rule
79
80
Enforces that calls to `PlatformColor()` and `DynamicColorIOS()` are statically analyzable to enable performance optimizations.
81
82
```javascript { .api }
83
/**
84
* ESLint rule for validating PlatformColor and DynamicColorIOS calls
85
*/
86
const platformColorsRule = {
87
meta: {
88
type: "problem",
89
docs: {
90
description: "Ensure that PlatformColor() and DynamicColorIOS() are passed literals of the expected shape."
91
},
92
messages: {
93
platformColorArgsLength: "PlatformColor() must have at least one argument that is a literal.",
94
platformColorArgTypes: "PlatformColor() every argument must be a literal.",
95
dynamicColorIOSArg: "DynamicColorIOS() must take a single argument of type Object",
96
dynamicColorIOSValue: "DynamicColorIOS() value must be either a literal or a PlatformColor() call."
97
},
98
schema: []
99
},
100
create: function(context) {
101
return {
102
CallExpression: function(node) {
103
// Rule implementation
104
}
105
};
106
}
107
};
108
```
109
110
**Rule Behavior:**
111
- Validates that `PlatformColor()` receives at least one literal argument
112
- Ensures all `PlatformColor()` arguments are literals (not variables or expressions)
113
- Validates that `DynamicColorIOS()` receives exactly one object expression argument
114
- Ensures `DynamicColorIOS()` object properties are either literals or `PlatformColor()` calls
115
116
**Usage Example:**
117
```javascript
118
// ✅ Valid - static literals
119
const color1 = PlatformColor("systemBlue", "blue");
120
const color2 = DynamicColorIOS({
121
light: "white",
122
dark: PlatformColor("systemBlack")
123
});
124
125
// ❌ Invalid - dynamic values
126
const colorName = "systemBlue";
127
const color3 = PlatformColor(colorName); // Error: arguments must be literals
128
```
129
130
### No Deep Imports Rule
131
132
Prevents deep imports from React Native internal modules and provides automatic fixes to use top-level imports instead.
133
134
```javascript { .api }
135
/**
136
* ESLint rule for preventing deep imports from React Native
137
*/
138
const noDeepImportsRule = {
139
meta: {
140
type: "problem",
141
docs: {
142
description: "Disallow deep imports from react native"
143
},
144
messages: {
145
deepImport: "'{{importPath}}' React Native deep imports are deprecated. Please use the top level import instead."
146
},
147
schema: [],
148
fixable: "code"
149
},
150
create: function(context) {
151
return {
152
ImportDeclaration: function(node) {
153
// Handle ES6 imports
154
},
155
CallExpression: function(node) {
156
// Handle CommonJS require() calls
157
}
158
};
159
}
160
};
161
```
162
163
**Rule Behavior:**
164
- Detects deep imports from `react-native/*` paths
165
- Provides automatic fixes using the public API mapping
166
- Handles both ES6 imports and CommonJS require() calls
167
- Supports default imports, named imports, and type imports
168
- Excludes valid internal imports like `react-native/Libraries/Core/InitializeCore`
169
170
**Usage Example:**
171
```javascript
172
// ❌ Invalid - deep import
173
import Button from "react-native/Libraries/Components/Button";
174
175
// ✅ Valid - top-level import (auto-fixed)
176
import { Button } from "react-native";
177
178
// ❌ Invalid - deep require
179
const Button = require("react-native/Libraries/Components/Button");
180
181
// ✅ Valid - top-level require (auto-fixed)
182
const { Button } = require("react-native");
183
```
184
185
### Public API Mapping Utility
186
187
Utility object that maps React Native internal module paths to their public API equivalents.
188
189
```javascript { .api }
190
/**
191
* Mapping of React Native internal paths to public API equivalents
192
* @type {Object.<string, {default: string|null, types: string[]|null}>}
193
*/
194
const publicAPIMapping = {
195
// Internal path as key, mapping info as value
196
"Libraries/Components/Button": {
197
default: "Button", // Public default export name
198
types: ["ButtonProps"] // Available type names for TypeScript
199
}
200
// ... 100+ more mappings
201
};
202
203
module.exports = {
204
publicAPIMapping
205
};
206
```
207
208
**Mapping Structure:**
209
- **Keys**: Internal React Native module paths (e.g., `"Libraries/Components/Button"`)
210
- **Values**: Objects with `default` (export name) and `types` (TypeScript types) properties
211
- **Coverage**: 100+ React Native components, APIs, utilities, and types
212
213
**Example Mappings:**
214
```javascript
215
const publicAPIMapping = {
216
"Libraries/Components/Button": {
217
default: "Button",
218
types: ["ButtonProps"]
219
},
220
"Libraries/Components/ActivityIndicator/ActivityIndicator": {
221
default: "ActivityIndicator",
222
types: ["ActivityIndicatorProps"]
223
},
224
"Libraries/Utilities/Platform": {
225
default: "Platform",
226
types: null
227
}
228
// ... 100+ more mappings
229
};
230
```
231
232
## Types
233
234
```javascript { .api }
235
/**
236
* ESLint rule metadata structure
237
* @typedef {Object} RuleMeta
238
* @property {"problem"|"suggestion"|"layout"} type - Rule type
239
* @property {Object} docs - Documentation object
240
* @property {string} docs.description - Rule description
241
* @property {Object.<string, string>} messages - Error message templates
242
* @property {Array} schema - JSON schema for rule options
243
* @property {"code"|"whitespace"} [fixable] - Whether rule provides fixes
244
*/
245
246
/**
247
* ESLint rule context object
248
* @typedef {Object} RuleContext
249
* @property {function} report - Report rule violations
250
*/
251
252
/**
253
* ESLint rule definition
254
* @typedef {Object} ESLintRule
255
* @property {RuleMeta} meta - Rule metadata
256
* @property {function} create - Creates rule visitor functions
257
*/
258
259
/**
260
* Public API mapping entry
261
* @typedef {Object.<string, {default: string|null, types: string[]|null}>} PublicAPIMapping
262
*/
263
264
/**
265
* Plugin export structure
266
* @typedef {Object} ESLintPlugin
267
* @property {Object.<string, ESLintRule>} rules - Available rules
268
*/
269
```