ESLint Plugin React Native provides React Native specific linting rules for ESLint, offering comprehensive code quality enforcement to catch common issues and enforce best practices in React Native development. The plugin includes rules for detecting unused styles, enforcing proper text wrapping, preventing inline styles, managing platform-specific components, and optimizing style definitions.
npm install --save-dev eslint-plugin-react-nativeThe plugin is configured through ESLint configuration files rather than imported directly in code:
{
"plugins": ["react-native"],
"extends": ["plugin:react-native/all"],
"env": {
"react-native/react-native": true
}
}{
"plugins": ["react-native"],
"rules": {
"react-native/no-unused-styles": "error",
"react-native/no-inline-styles": "error",
"react-native/no-color-literals": "error",
"react-native/no-raw-text": "error",
"react-native/sort-styles": ["error", "asc"],
"react-native/split-platform-components": "error",
"react-native/no-single-element-style-arrays": "error"
},
"settings": {
"react-native/style-sheet-object-names": ["StyleSheet", "EStyleSheet"]
}
}ESLint Plugin React Native is built around several key components:
meta and create functionsRules focused on StyleSheet usage, optimization, and best practices including unused style detection and style organization.
// Rule: no-unused-styles
module.exports = {
meta: { schema: [] },
create: function(context) { /* ... */ }
};
// Rule: sort-styles
module.exports = {
meta: {
fixable: "code",
schema: [
{ enum: ["asc", "desc"] },
{
type: "object",
properties: {
ignoreClassNames: { type: "boolean" },
ignoreStyleProperties: { type: "boolean" }
}
}
]
},
create: function(context) { /* ... */ }
};Rules that enforce style quality standards including inline style detection and color literal prevention.
// Rule: no-inline-styles
module.exports = {
meta: { schema: [] },
create: function(context) { /* ... */ }
};
// Rule: no-color-literals
module.exports = {
meta: { schema: [] },
create: function(context) { /* ... */ }
};
// Rule: no-single-element-style-arrays
module.exports = {
meta: { fixable: "code" },
create: function(context) { /* ... */ }
};Rules that manage React Native component usage patterns and platform-specific requirements.
// Rule: split-platform-components
module.exports = {
meta: {
fixable: "code",
schema: [{
type: "object",
properties: {
androidPathRegex: { type: "string" },
iosPathRegex: { type: "string" }
}
}]
},
create: function(context) { /* ... */ }
};
// Rule: no-raw-text
module.exports = {
meta: {
schema: [{
type: "object",
properties: {
skip: {
type: "array",
items: { type: "string" }
}
}
}]
},
create: function(context) { /* ... */ }
};Configuration options, shareable configs, and environment settings.
// Main plugin export
module.exports = {
rules: { /* All rules */ },
rulesConfig: { /* Default rule configurations */ },
deprecatedRules: {},
environments: {
"react-native": {
globals: { /* React Native globals */ }
}
},
configs: {
all: {
plugins: ["react-native"],
parserOptions: {
ecmaFeatures: { jsx: true }
},
rules: { /* All rules enabled as errors */ }
}
}
};// ESLint Rule Interface
interface ESLintRule {
meta: {
schema?: any[];
fixable?: "code" | "whitespace";
docs?: {
description?: string;
category?: string;
recommended?: boolean;
url?: string;
};
};
create: (context: ESLintContext) => ESLintVisitors;
}
interface ESLintContext {
getSourceCode(): SourceCode;
getFilename(): string;
getScope(node?: ESTree.Node): Scope;
report(descriptor: ReportDescriptor): void;
settings: { [key: string]: any };
options: any[];
}
interface ReportDescriptor {
node: ESTree.Node;
message: string;
data?: { [key: string]: string };
fix?(fixer: RuleFixer): Fix | Fix[] | null;
loc?: SourceLocation;
}
// Plugin Configuration Types
interface PluginExport {
rules: { [ruleName: string]: ESLintRule };
rulesConfig: { [ruleName: string]: number };
deprecatedRules: { [ruleName: string]: ESLintRule };
environments: { [envName: string]: Environment };
configs: { [configName: string]: Config };
}
interface Environment {
globals: { [globalName: string]: boolean };
}
interface Config {
plugins: string[];
parserOptions?: {
ecmaFeatures?: { jsx?: boolean };
};
rules: { [ruleName: string]: number | [number, ...any[]] };
}