React Native Accessibility ESLint Rules
eslint-plugin-react-native-a11y is an ESLint plugin specifically designed to identify common accessibility issues within React Native applications. It extends the principles of web accessibility linters like `eslint-plugin-jsx-a11y` by providing rules tailored to React Native's unique component structure and accessibility APIs. The plugin offers real-time feedback during development, helping teams create more inclusive and navigable experiences for users with screen readers and other assistive technologies. Currently stable at version `3.5.1`, it sees an active development pace with frequent patch and minor releases addressing bug fixes and new features. A key differentiator is its ability to offer platform-specific configurations (`basic`, `ios`, `android`, `all`) to optimize linting for projects targeting particular environments.
Common errors
-
Error: Failed to load plugin 'react-native-a11y' relative to '...' The package 'eslint-plugin-react-native-a11y' was not found.
cause The plugin package is not installed or not discoverable by ESLint. This can happen due to local vs. global installation mismatch or incomplete `npm install`.fixRun `npm install eslint-plugin-react-native-a11y --save-dev` in your project's root directory. If ESLint is globally installed, ensure the plugin is also globally installed (though local installation is recommended). -
Error: There was a problem loading formatter: .\node_modules\eslint\lib\cli-engine\formatters\stylish Error: require() of ES Module ...
cause This error can occur when there are multiple conflicting versions of ESLint or its plugins installed within your project's `node_modules`, often due to transitive dependencies, or when mixing CommonJS (`require`) with ESM (`import`) configurations.fixUse `npm list eslint` or `yarn list eslint` to check for duplicate `eslint` packages. If conflicts exist, try `npm install --force` or `yarn install --force` to resolve peer dependency issues, or use `resolutions` in `package.json` for specific packages if necessary. Ensure your ESLint config aligns with your project's module type (CommonJS or ESM). -
Error: Configuration for rule "react-native-a11y/rule-name" is invalid:
cause The configuration provided for a specific rule is syntactically incorrect, uses an invalid option, or the rule name itself is misspelled or not recognized.fixDouble-check the rule name for typos and consult the official documentation for the `eslint-plugin-react-native-a11y` rules to ensure valid options and syntax are used in your `.eslintrc.js` file. For instance, `has-accessibility-props` accepts an array of `touchableComponents`.
Warnings
- breaking Version 3.0.0 of `eslint-plugin-react-native-a11y` removed support for Node.js 10. Users on Node.js 10 or older environments will encounter errors if they upgrade to v3.0.0 or higher.
- gotcha When migrating to ESLint 9, users may encounter compatibility issues with `has-valid-accessibility-ignores-invert-colors` rule, leading to linting failures or incorrect reporting.
- gotcha Installing ESLint plugins globally can lead to unexpected behavior or `plugin not found` errors, especially when project dependencies or configurations differ from the global setup.
- gotcha Incorrectly configuring the plugin in `.eslintrc.js` by omitting the `plugin:` prefix for `extends` values (e.g., `extends: ['react-native-a11y/all']`) will cause ESLint to fail to load the configuration.
Install
-
npm install eslint-plugin-react-native-a11y -
yarn add eslint-plugin-react-native-a11y -
pnpm add eslint-plugin-react-native-a11y
Imports
- plugin:react-native-a11y/all
extends: ['react-native-a11y/all']
extends: ['plugin:react-native-a11y/all']
- plugin:react-native-a11y/ios
extends: ['react-native-a11y/ios']
extends: ['plugin:react-native-a11y/ios']
- 'react-native-a11y/has-accessibility-hint'
rules: { 'has-accessibility-hint': 'error' }rules: { 'react-native-a11y/has-accessibility-hint': 'error' }
Quickstart
{
"name": "my-react-native-app",
"version": "1.0.0",
"private": true,
"devDependencies": {
"eslint": "^8.0.0",
"eslint-plugin-react-native-a11y": "^3.5.1"
}
}
// .eslintrc.js
module.exports = {
root: true,
extends: [
// Assuming you have an existing React Native ESLint config
// e.g., '@react-native-community'
// 'plugin:react-native-a11y/basic', // For basic rules common to both platforms
// 'plugin:react-native-a11y/ios', // For iOS-specific rules
// 'plugin:react-native-a11y/android', // For Android-specific rules
'plugin:react-native-a11y/all' // For all rules (most comprehensive)
],
parserOptions: {
ecmaFeatures: {
jsx: true
}
},
rules: {
// Example of overriding a rule or adding a specific one
// 'react-native-a11y/has-valid-accessibility-role': 'error',
// 'react-native-a11y/has-accessibility-props': ['warn', {
// touchableComponents: ['TouchableOpacity', 'TouchableHighlight', 'TouchableWithoutFeedback', 'Pressable']
// }]
}
};