The Overlay Factsheet describes an accessibility overlay as follows:
“Overlays are a broad term for technologies that aim to improve the accessibility of a website. They apply third-party source code (typically JavaScript) to make improvements to the front-end code of the website.”
There are a number of different accessibility overlays on the market, but the most popular ones have three main features:
- The “widget” which presents a UI that modifies the web page appearance and operation to, ostensibly, improve the usability of the web page
- A global set of utilities aimed at applying JavaScript to fix common issues
- An ability to push “custom” fixes to the web page. These are apparently developed by developers at the overlay vendor and also use JavaScript. This is sold as a service and often comes at a much higher price.
For lack of a better term, we’ll call those last two features “Post-rendered remediation”. In other words, they attempt to make fixes to the web page after the page has been rendered in the user’s browser.
On the surface, this seems very promising. JavaScript can be used to add, remove, or modify elements and attributes on the page and modify CSS to change the appearance and layout. It truly is the perfect technology for this task. In practice, it doesn’t really work. The Overlay Factsheet discusses the many reasons why. I’d like to provide a deep discussion on the 4th item identified in that list: the difficulty remediating accessibility problems in React, Angular, Vue, etc.
Background on the experiment
Although I already knew the limitations in attempting to use external JS to fix issues in React, Angular, and Vue, I wanted to be able to itemize the challenges in detail. To do so, I created a series of React components that represent common UI widgets found on the web. I made them inaccessible on purpose, but with realistic, common accessibility errors. Then, I created external JavaScript files aimed at fixing the accessibility problems. In my opinion, this represents the most optimistic scenario for an overlay vendor: itemized knowledge of the exact problems in the component(s) and completely custom approach to fixing them, unencumbered by any potential product limitations inherent in an overlay vendor’s systems. In other words, I wanted to show what’s possible, not what the overlays actually do. So, as you read this, keep in mind that the remediation approaches exhibited all involve having direct knowledge of each component’s code, at which point it really would make the most sense to just fix the customer’s code in the first place.
Results: What things are impossible for overlays to fix?
Everything discussed here is available in a public repository on GitHub: https://github.com/AFixt/autofix-challenges at which anyone can access 100% of the work upon which the below information is based. Feel free to use that repo to verify or dispute what’s said below. The components – and their attempted repairs – can be seen in the repo.
The fundamental constraint you will notice as you dive into the details below is that post-rendered remediation is working against the framework, not with it. React (and similar frameworks) own the DOM. The framework expects to be the single source of truth for element structure, attributes, and event handlers. Every remediation fix is fighting this ownership model:
- Attributes are ephemeral. React re-renders erase the changes. The fix must continuously re-apply throughout the component lifecycle.
- Structure is immutable.
<divs>cannot become semantic elements. ARIA is the only option, and this is always a weaker substitute to native semantics. - State is opaque. The fixes cannot read React state; they must reverse-engineer state from CSS classes and DOM structure. Change any of that during ongoing maintenance of the underlying code, and the fix dies.
- Events are synthetic. The fixes cannot trigger React state updates directly; they must simulate clicks and hope the component responds.
- Timing is adversarial. There is always a gap between a DOM change and the fix re-applying, during which assistive technology sees stale or missing information.
These problems are compounded when content changes asynchronously (XHR responses, WebSocket updates, polling). The remediation layer has no awareness of pending data fetches. It can only react after the DOM has already changed, widening the gap during which assistive technology sees un-remediated content. User-initiated changes at least follow a predictable interaction→render cycle; server-driven updates arrive at arbitrary times, making the MutationObserver‘s debounce window a more frequent source of stale or missing announcements.
These are not implementation bugs. They are inherent limitations of the overlay approach. No amount of engineering can fully overcome them. You can see the fully itemized list of auto-repair limitations in the repository.
Across all 29 components, there are 292 intentional accessibility issues. Of them only 46% of issues are reliably remediated. The remaining 54% are either impossible to fix (12%) or depend on assumptions that break silently when the component is refactored, restyled, or re-rendered (42%). The fixes that do work require continuous re-application via MutationObserver, adding runtime overhead and an inherent brittleness that does not exist when accessibility is built into the component source.
This isn’t just a React thing. This is true for all major component-based UI frameworks
Accessibility overlay vendors market their products as framework-agnostic solutions. The premise is that since the browser sees the same DOM regardless of framework, a single remediation layer can fix accessibility issues across any technology stack.
This premise is technically true for a narrow category of fixes like adding `aria-label` to a static element, setting `role` on a div that never re-renders, or adding `tabindex` to a non-interactive element on a page that does not use client-side rendering. These are the “reasonably fixed” 46% from the React findings.
For the remaining 54% of issues that are either impossible or fragile, the framework matters. Each framework has its own rendering cycle, event system, encapsulation model, and state management strategy. A remediation layer must account for all of them simultaneously when deployed on pages that mix frameworks (micro-frontends, widget embeds, third-party components). The combinatorial complexity makes reliable remediation intractable at scale.
The 54% problem is a floor, not a ceiling
The 54% of issues that are unfixable or fragile in React actually represents the best case. React’s synthetic event system is relatively predictable, its reconciliation algorithm is well-documented, and it does not use shadow DOM by default. Angular’s Zone.js, Vue’s transition classes, Svelte’s compiled modifiers, and Lit’s shadow DOM each add new failure modes that push the fragile percentage higher.
No controlled study of these frameworks has been conducted in this project, but the architectural analysis strongly suggests:
- Angular: ~55–60% unfixable or fragile (Zone.js re-render frequency, encapsulated styles)
- Vue: ~55–58% unfixable or fragile (transition class interference, aggressive key-based diffing)
- Svelte: ~54–57% unfixable or fragile (compiled event modifiers, hashed class names in production)
- Lit/Web Components: ~65–75% unfixable or fragile (shadow DOM makes entire component subtrees unreachable)
The fundamental constraint is universal
The sentence from above applies to every framework covered here: Post-render remediation is working against the framework, not with it.
Replace “React” with any framework name and the five properties I already mentioned still hold:
- Attributes are ephemeral: the framework re-renders and erases them
- Structure is immutable: divs cannot become semantic elements
- State is opaque: it must be reverse-engineered from DOM artifacts
- Events are synthetic: the remediation cannot trigger state updates directly
- Timing is adversarial: there is always a gap between DOM change and re-remediation
These are not implementation details that better engineering can overcome. They are consequences of the component model itself. Any system that renders DOM from internal state and expects to be the sole writer of that DOM will resist external modification. This is true today and will remain true as frameworks evolve, because the component model’s value propositions around encapsulation, composability, and declarative rendering is precisely what makes external remediation unreliable.
Even the successful repairs are impossible to maintain in the long-term
Some may attempt to argue that fixing 46% is “better than nothing”. But there are two main enemies to post-rendered remediation approaches like this: the site owner maintaining their website and the site owner discontinuing the overlay contract.
Websites are never just deployed and left alone, especially if it is one that earns the site owner money. E-commerce sites and SaaS platforms are under constant maintenance and change. Even if a website is a simple e-commerce store on Shopify using a theme from the marketplace, the site owner is going to add plugins, change settings, and perform updates. Every single change is a new opportunity to break the custom code used to repair the issues, because effectively doing so means tying the repairs to something that might change during maintenance. Applying a custom repair requires identifying what you’re repairing so the JavaScript knows what to act on. There are a lot of ways to select what you want to work on, but all of them have their own challenges when it comes to accurately selecting what you want to repair. If you select an element by its id and that id changes, the repair breaks. If you select an element by its className and the className changes, the repair breaks. If your selection is too broad, you might break something unrelated to what you want to fix. It all just ends up becoming Accessibility Jenga: pull the wrong piece and it all falls apart.
Then there’s the dependency on maintaining the contract. Ultimately, when purchasing an overlay and opting for the seemingly white-gloved approach of custom fixes leads you down a path where you don’t own the accessibility of your website. The overlay vendor owns the accessibility of your website (well, the 46% of issues that it can repair) and has you locked into a subscription model where as soon as you end the subscription, all of it is gone. Its all a bit like paying a subscription fee to have airbags and seatbelts in your car.
Just fix it
“If its worth doing, its worth doing right”, my dad would always say. Yours probably did, too. And he wasn’t wrong. It is easy to be attracted to solutions that appear to address a critical compliance concern quickly and with minimal distraction. It is also easy to believe the claims made by companies with tens-of-thousands of customers (even though they get sued by customers for false claims). It is also easy to believe that their monthly subscription fees are cheaper than hiring accessibility experts (even though that’s not true). The harsh, unsexy truth, is that just fixing the actual site is the single most effective solution, both in the short and long term. It is the approach advocated by over 1000 accessibility experts and advocates across the globe.


