Generated interface code has a consistent set of gaps, which is good news: a consistent failure is a checklist. What follows is what to look for, in the order that catches the most for the least effort. It applies equally to a component an agent wrote and one it installed from a catalogue, because the gaps are the same.
First: does it exist in the HTML
The check that catches the most expensive mistakes.
Is the text there before JavaScript runs? View source, or disable JavaScript. A headline that only appears after hydration is invisible to search engines, answer engines and anyone on a slow connection. Animated headlines and canvas text are the usual causes.
Is it a client component that did not need to be? State, effects, refs, browser APIs and event handlers are the four reasons for a client directive. Generated components have it by default. The server components guide covers pushing the boundary down.
Are links real links? An onClick that calls the router is not a link: no middle-click, no open in new tab, no crawler. This is the most common structural error in generated markup.
Second: the keyboard
Four checks, thirty seconds, and they catch what nobody notices until someone complains.
Tab through it. Every interactive element should be reachable, in a sensible order, with a visible focus indicator. A removed outline with nothing replacing it is the single commonest accessibility failure in generated code.
Escape and focus return. Anything that opens over the page traps focus and returns it on close.
Arrow keys where they belong. Tabs, menus and grids use a roving tabindex, not one tab stop per item.
The icon-only buttons. Every one needs an accessible name. A toolbar of unlabelled icons is invisible to a screen reader.
Third: the states nobody generates
Generated components render the happy path. Real screens have four more, and all four are usually missing: loading, empty, error and permission. The empty state guide covers why the empty one matters most - it is the first screen every new account sees.
Also check the states of the controls themselves: hover, active, focus-visible, loading and disabled. Most generated components ship three of the six.
Fourth: motion and preferences
prefers-reduced-motion. Every animation needs a branch that renders the end state, not a shorter duration. Generated code almost never includes one.
Colour alone. A status shown only as a green or red dot is unreadable for a significant share of readers. Pair it with a word or a shape.
Contrast at the real size. Small muted text on a card is where themes fail 4.5:1, and it fails everywhere at once because it is a token.
Fifth: what it dragged in
Generated components import generously. Check three things: whether it pulled an animation library for one transition, whether it added an icon set you already have under another name, and whether it introduced a second date or utility library alongside your existing one.
Then check the class names against your tokens. A component using bg-zinc-900 instead of bg-background looks right today and will silently miss every future theme change.
Sixth: is it the right component at all
The check a model cannot do for you, and the one that matters most.
Should that dialog have been a page with an address? Should the carousel have been a list? Should the tabs have been sections? Should the tooltip, which does not exist on touch, have been visible text? Each of those guides makes the same point from its own side: the catalogue answers what exists, and the judgement is yours.
The short version
If you only do three: view source and find the headline, press Tab through the whole screen, and search the file for a hardcoded colour. Those three catch most of what actually reaches production.
Where else to look
The honest list, because the answer is not always us:
| Source | Best for | Trade-off |
|---|---|---|
| An automated accessibility checker | Contrast, names and roles, in seconds | Catches a fraction of real problems |
| A keyboard and a screen reader | Almost everything a checker misses | Takes a person a few minutes |
| A bundle analyser | What the component dragged in | Only tells you the size, not whether it is needed |
| 21st | Components with the source visible before you install | Quality varies by author, so run the same checks |
Taking one
Every component page has a live preview and the code. Installing goes through the shadcn CLI against our registry:
That key comes from your 21st account, and installs require a membership. Set API_KEY_21ST once in your shell and the command works for anything in the catalogue.
Frequently asked
- What do you check first in generated UI code?
- Whether the content exists in the HTML before JavaScript runs. A headline that appears only after hydration is invisible to search engines, answer engines and anyone on a slow connection, and animated headlines and canvas text are the usual causes. Then whether links are real anchors rather than click handlers.
- What accessibility gaps are most common in generated components?
- A removed focus outline with nothing replacing it, icon-only buttons with no accessible name, arrow-key navigation missing from tabs and menus, and no reduced-motion branch on any animation. All four are quick to check and all four are usually absent.
- What states does generated code usually miss?
- Everything but the happy path: loading, empty, error and permission at the screen level, and hover, focus-visible, loading and disabled at the control level. Most generated components ship three of the six control states and none of the four screen states.
- What is the fastest useful review?
- Three things: view source and find the headline, press Tab through the whole screen watching for a visible focus indicator, and search the file for a hardcoded colour such as bg-zinc-900. Those catch most of what actually reaches production.



