eslint-plugin-jsx-a11y is a static analysis ESLint plugin that enforces accessibility rules on JSX elements, and while it is not a vulnerability scanner, it plays a real role in a secure and compliant React codebase. People searching for eslint-plugin-jsx-a11y in a security context usually want two answers: does it find security bugs, and can I trust it as a dependency? The short version is that it finds accessibility defects, not injection flaws, but treating accessibility as out of scope for security is a mistake once legal and contractual compliance enter the picture.
What eslint-plugin-jsx-a11y actually does
The plugin performs a static evaluation of the JSX you write and flags accessibility issues at the code level. It ships as an ESLint plugin, so it runs during linting rather than at runtime. Typical rules cover things like alt-text (images must have alternative text), anchor-is-valid (anchors must point somewhere real), label-has-associated-control (form inputs need labels), and no-autofocus. Create React App has bundled it by default for years, which is why so many React developers already have it in their dependency tree without having chosen it deliberately.
Here is a minimal setup in a flat config:
// eslint.config.js
import jsxA11y from "eslint-plugin-jsx-a11y";
export default [
{
files: ["**/*.jsx", "**/*.tsx"],
plugins: { "jsx-a11y": jsxA11y },
rules: {
...jsxA11y.configs.recommended.rules,
"jsx-a11y/no-autofocus": "warn",
},
},
];
The plugin is a static AST checker. It reads your source, walks the syntax tree, and reports rule violations. It never renders a component, never hits a browser, and never inspects network traffic.
Is it a security tool, honestly?
No, not in the sense most people mean when they say "security scanner." It does not detect cross-site scripting, insecure dangerouslySetInnerHTML usage, hardcoded secrets, or vulnerable dependencies. Those belong to other tools: eslint-plugin-security, eslint-plugin-react for some unsafe patterns, and a dedicated software composition analysis (SCA) scanner for the dependency graph.
Where the line blurs is compliance. Accessibility is a legal requirement in many jurisdictions — think the Americans with Disabilities Act, Section 508, and the European Accessibility Act. A failed accessibility audit can carry the same business consequences as a failed security audit: remediation cost, contract loss, and reputational damage. If your threat model includes "we get sued or lose a government contract," then an accessibility linter is part of your risk posture even though it never touches a CVE.
The limits you need to plan around
The most important limitation is that static analysis only sees static code. The plugin cannot evaluate anything computed at runtime. If a component builds its aria-label from a prop, a context value, or a fetched string, the plugin has no way to know whether the final rendered output is accessible. The maintainers are explicit that it should be paired with a runtime checker such as @axe-core/react, which inspects the actual rendered DOM in a browser.
A few concrete blind spots:
- Dynamically generated roles and ARIA attributes pass linting but can still be wrong at runtime.
- Color contrast is invisible to the plugin because contrast depends on computed CSS, not JSX structure.
- Focus order and keyboard trap issues emerge from the rendered tree, not the source.
Treat the plugin as your first gate, not your only one.
Trusting it as a dependency
The second security question about eslint-plugin-jsx-a11y is supply-chain trust: it is an npm package that runs during your build, so it is code you execute. The package is maintained under the jsx-eslint organization, which also stewards eslint-plugin-react, and it is one of the more widely depended-on dev tools in the JavaScript ecosystem. That does not make it immune to compromise. Any dev dependency that runs in CI is part of your attack surface, and build-time packages have been a favored target — the broader npm ecosystem has seen maintainer account takeovers and malicious version pushes repeatedly.
The defensive practices are the same as for any npm dependency:
- Pin exact versions with a committed lockfile and run
npm ci, notnpm install, in CI. - Watch for unexpected version jumps in a package that normally moves slowly.
- Run an SCA scan across your dev and production dependencies so a malicious or vulnerable transitive package gets flagged. An SCA tool such as Safeguard can surface risk in build-time dependencies, not just the ones that ship to production.
Fitting it into a secure React pipeline
Accessibility linting, security linting, and dependency scanning are three separate layers, and you want all three. A sensible layering looks like this:
eslint-plugin-jsx-a11ycatches accessibility defects in source during lint.@axe-core/react(or Playwright plus axe) catches accessibility defects in the rendered DOM during test.- A security-focused ESLint config plus SCA covers code-level unsafe patterns and vulnerable packages.
Run the linter in a pre-commit hook and again in CI so nothing merges with new violations. Keep the rule set at recommended to start, then ratchet individual rules up to error as your team closes out the backlog. If you are building out your team's knowledge here, the fundamentals of static analysis and where it fits are worth reviewing in the Safeguard Academy.
Common mistakes teams make
The recurring one is assuming a green lint run means an accessible app. It does not — it means your source has no statically detectable violations. The second mistake is disabling rules wholesale to clear a noisy backlog instead of fixing the underlying markup; a suppressed jsx-a11y/anchor-is-valid is still a broken link for a screen reader user. The third is forgetting that the plugin runs your build, so it deserves the same dependency hygiene as everything else in package.json.
FAQ
Does eslint-plugin-jsx-a11y find security vulnerabilities?
No. It finds accessibility issues in JSX through static analysis. For code-level security issues use a security-focused ESLint config, and for vulnerable dependencies use a software composition analysis scanner.
Is eslint-plugin-jsx-a11y enough for accessibility compliance?
Not on its own. It only evaluates static code and cannot see runtime-computed attributes, color contrast, or focus behavior. Pair it with a DOM-level tool like @axe-core/react and manual testing with a screen reader.
Is eslint-plugin-jsx-a11y safe to use?
It is a widely used, actively maintained plugin under the jsx-eslint organization. Like any dev dependency it runs during your build, so pin versions, commit a lockfile, and scan your dependency graph so a compromised release would be caught.
Do I need to install it manually with Create React App?
No. Create React App bundles eslint-plugin-jsx-a11y by default. For custom setups such as Vite or a bare ESLint flat config, add it as a dev dependency and register the plugin explicitly.