Framework parity
The four libraries emit the same classes, so anything they both ship looks identical. They do not, however, ship the same things. This page is generated from the same registry as the component pages, so it cannot flatter the truth.
The same UI, four libraries
React, Vue and Svelte are real islands, hydrated by their own package — not screenshots. None of them sets a theme; they all inherit data-theme from the page, so the toggles in the header repaint every column at once.
React
Vue
Svelte
Angular
Astro cannot host an Angular island here: Angular 22 requires TypeScript 6 while the Svelte integration requires TypeScript 5, and @analogjs/astro-angular's Vite plugin takes over every .ts file in the project, breaking the other three renderers. So this column is rendered at build time from the Angular package's own class helpers — the file it calls "the visual-parity contract". Its markup is real; only its interactivity is missing.
Coverage
| Component | React | Vue | Svelte | Angular |
|---|---|---|---|---|
| Theming | ||||
| AuraProvider | ● | ● | ● | ● |
| Primitives | ||||
| Typography | ● | ● | ● | ● |
| Button | ● | ● | ● | ● |
| Card | ● | ● | ● | ● |
| Badge | ● | ● | ● | ● |
| IconButton | ● | ● | ● | ● |
| Chip | ● | ● | ● | ● |
| Switch | ● | ● | ● | ◐ |
| Field | ● | ● | ● | ● |
| Scroll | ● | ● | ● | ● |
| Checkbox | ● | ● | ● | ● |
| RadioGroup | ● | ● | ● | ● |
| Radio | ● | ● | ● | ● |
| Textarea | ● | ● | ● | ● |
| Select | ● | ● | ● | ● |
| MultiSelect | ● | ● | ● | ● |
| Fieldset | ● | ● | ● | ● |
| Accordion | ● | ● | ● | ● |
| SegmentedControl | ● | ● | ● | ● |
| Alert | ● | ● | ● | ● |
| Avatar | ● | ● | ● | ● |
| AvatarGroup | ● | ● | ● | ● |
| Skeleton | ● | ● | ● | ● |
| Loader | ● | ● | ● | ● |
| Progress | ● | ● | ● | ● |
| Code | ▣ | ▣ | ▣ | ▣ |
| Blockquote | ▣ | ▣ | ▣ | ▣ |
| List | ● | ● | ● | ● |
| Mark | ▣ | ▣ | ▣ | ▣ |
| Anchor | ▣ | ▣ | ▣ | ▣ |
| Indicator | ● | ● | ● | ● |
| RingProgress | ● | ● | ● | ● |
| Toast | ● | ● | ● | ● |
| Tabs | ● | ● | ● | ● |
| Dialog | ● | ● | ● | ● |
| Popover | ● | ● | ● | ● |
| Menu | ● | ● | ● | ● |
| Tooltip | ● | ● | ● | ● |
| HabitHeatmap | ● | ● | ● | ● |
| DataTable | ● | ● | ● | ● |
| StepWizard | ● | ● | ● | ● |
| TimeGrid | ● | ● | ● | ● |
| Layout | ||||
| Stack | ● | ● | ● | ● |
| Flex | ● | ● | ● | ● |
| Group | ● | ● | ● | ● |
| Grid | ● | ● | ● | ● |
| Container | ● | ● | ● | ● |
| Masonry | ● | ● | ● | ● |
| Divider | ● | ● | ● | ◐ |
| Spacer | ▣ | ▣ | ▣ | ▣ |
| Recipes | ||||
| StatBadge | ◇ | ◇ | ◇ | ◇ |
| CalloutList | ◇ | ◇ | ◇ | ◇ |
| ProgressCard | ◇ | ◇ | ◇ | ◇ |
| FormDialog | ◇ | ◇ | ◇ | ◇ |
| CommandPalette | ◇ | ◇ | ◇ | ◇ |
- ●matches React
- ◐shipped with documented differences
- ○not ported
- ▣a class, no wrapper needed
- ◇an example, nothing to install
What the map does not say
The four libraries still spell things their own way, and the per-component tables say so: a callback in React (onCheckedChange) is an emit in Vue (update:modelValue), a callback prop in Svelte (onchange) and an output in Angular (checkedChange). What is guaranteed is the DOM and the classes — not the prop names.
Its primitives are directives, so the selector stays on the element (<button auraButton class="aura-btn">), and the few components that need a tag of their own add one (<aura-field>, <aura-chip>). Those hosts are display: contents, so they add no box and the layout is the same — but the tree is not literally identical to the other three.