« All posts

AI-Generated UI Is Inaccessible by Default

AI code-gen tools produce visually polished but semantically empty React UI. A five-layer system enforces real accessibility tree correctness.

Code-generation tools like Claude Code, Cursor, and Copilot can produce a polished-looking React sidebar in seconds, yet the browser's accessibility tree often reports role generic, name none for the same markup. For screen reader, keyboard, and voice-control users, the component effectively doesn't exist. The root cause is architectural: LLMs optimize for visual fidelity while generating near-zero semantic information for the DOM layer assistive technologies actually read, reinforced by div-heavy training data, visually-biased feedback loops, and token economics that favor shorter, semantic-free markup.

A representative sidebar example surfaces ten distinct failures in twenty-nine lines missing landmarks, fake buttons built from clickable divs, no keyboard handling, absent ARIA state like aria-expanded, and unlabeled icons. Specialized tools such as Vercel's v0, which emits Radix-based shadcn/ui components, largely sidestep this by inheriting accessible primitives by default. But general-purpose tools most developers rely on daily still produce the same div soup.

The proposed fix is a five-layer enforcement system: persistent prompt constraints baked into workspace config, static analysis, runtime testing, CI integration, and accessible component abstractions. For engineers, the takeaway is that AI-generated UI must be verified against the accessibility tree, not just visual output, and that semantic correctness needs to be enforced systematically rather than assumed.

This synthesis was produced from its source by AI; there is no human editor or manual review step. How we work