Cross-reference of every component shipped in @freecodecamp/uikit against
three widely-used React headless / styled libraries, plus a pointer to the
primary accessibility spec (WAI-ARIA APG in most cases). Source of truth
for UIKit rows is packages/uikit/src/<layer>/index.ts barrel exports.
- ✅ Shipped (dedicated component)
- 🟡 Partial (similar primitive exists, different API surface)
- ⬜ Absent / not offered
🅰️ Ark-backed (machine provided by@zag-js/*under the hood)
External library versions reflected: Catalyst (Tailwind Catalyst v2 as
of 2026-04), Ark UI (@ark-ui/react 3.x), Headless UI (@headlessui/react 2.x).
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Avatar | ✅ | ✅ | ✅ | ⬜ | ARIA: img |
| Badge | ✅ | ✅ | ⬜ | ⬜ | - (decorative) |
| Button | ✅ | ✅ | ✅ | ✅ | APG · Button |
| CloseButton | ✅ | ⬜ | ⬜ | ⬜ | APG · Button |
| Divider | ✅ | ✅ | ⬜ | ⬜ | ARIA: separator |
| Heading | ✅ | ✅ | ⬜ | ⬜ | HTML: heading content |
| Image | ✅ | ⬜ | ⬜ | ⬜ | HTML: img |
| Link | ✅ | ✅ | ⬜ | ⬜ | APG · Link |
| Spacer | ✅ | ⬜ | ⬜ | ⬜ | - (layout helper) |
| Text | ✅ | ✅ | ⬜ | ⬜ | - (polymorphic typographic wrapper) |
Gaps: Catalyst does not ship a dedicated Spacer, Image, or CloseButton -
Tailwind spacing utilities cover it. Ark UI is pure headless primitive-set; it
skips visual-only atoms like Badge and Spacer.
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Button | ✅ | ✅ | ✅ | ✅ | APG · Button |
| ToggleButton | ✅ | 🟡 | ✅ | ⬜ | APG · Button (toggle) |
| CloseButton | ✅ | ⬜ | ⬜ | ⬜ | APG · Button |
Gaps: Catalyst uses a data-slot="button" variant for toggle state rather
than a dedicated component. Headless UI funnels these through the generic
Button primitive.
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Input | ✅ | ✅ | 🟡 (via Field) | ✅ | APG · Textbox |
| Textarea | ✅ | ✅ | 🟡 | ✅ | APG · Textbox (multiline) |
| Select | ✅ | ✅ | ✅ | ✅ | APG · Combobox |
| Checkbox | ✅ | ✅ | ✅ | ✅ | APG · Checkbox |
| Radio / RadioGroup | ✅ | ✅ | ✅ | ✅ | APG · Radio Group |
| Switch | ✅ | ✅ | ✅ | ✅ | APG · Switch |
| Fieldset | ✅ | ✅ | 🟡 (Field) | ✅ (Fieldset) | HTML: fieldset |
| FormControl | ✅ | 🟡 | ✅ (Field) | APG · Form field | |
| FormGroup | ✅ | ⬜ | ⬜ | ⬜ | ARIA: group |
| HelpBlock | ✅ | 🟡 (Description) | 🟡 (Description) | ARIA: aria-describedby | |
| FormStepper | ✅ | ⬜ | ⬜ | APG · Feed (loose fit) |
Gaps: Catalyst bundles the "label + control + description + error" quartet
into a single Field + Description compound rather than exposing
FormControl/HelpBlock separately. FormStepper is uncommon outside
Ark's Steps.
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Navbar | ✅ | ✅ | ⬜ | ⬜ | APG · Landmark: banner |
| Sidebar | ✅ | ✅ | ⬜ | ⬜ | APG · Landmark: navigation |
| Tabs | ✅ | ⬜ | ✅ | ✅ | APG · Tabs |
| Pagination | ✅ | ✅ | ✅ | ⬜ | APG · Navigation (Pagination) |
| Listbox | ✅ | ⬜ | ✅ | ✅ | APG · Listbox |
| Combobox | ✅ | ✅ | ✅ | ✅ | APG · Combobox |
Gaps: Catalyst focuses on chrome (Navbar, Sidebar) and skips the
Tabs + Listbox primitives (Headless UI is the Tailwind-native answer
for those).
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Modal | ✅ | ✅ (Dialog) | ✅ | ✅ (Dialog) | APG · Dialog |
| Dropdown | ✅ | ✅ | ✅ (Menu) | ✅ (Menu) | APG · Menu Button |
| Tooltip | ✅ | ⬜ | ✅ | ⬜ | APG · Tooltip |
| Toast / Toaster | ✅ | ⬜ | ✅ | ⬜ | APG · Alert (live region) |
| CommandPalette | ✅ | ⬜ | 🟡 (Combobox+Dialog) | ⬜ | APG · Combobox + Dialog |
Gaps: Catalyst and Headless UI both defer Toast and CommandPalette to
third-party adapters (sonner, cmdk). UIKit ships them as first-class.
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Alert | ✅ | ⬜ | ⬜ | ⬜ | APG · Alert |
| Callout | ✅ | ⬜ | ⬜ | ⬜ | - (styled note block) |
| Skeleton | ✅ | ⬜ | ⬜ | ⬜ | ARIA: aria-busy |
| EmptyState | ✅ | 🟡 | ⬜ | ⬜ | - (compositional pattern) |
Gaps: None of the external three ship dedicated feedback primitives - the Tailwind ecosystem treats these as recipe patterns. UIKit ships them as structural components so the semantics (role, live-region, busy) travel with the DOM.
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| Card | ✅ | ⬜ | ⬜ | ⬜ | - (pattern) |
| Panel | ✅ | ⬜ | ⬜ | ⬜ | ARIA: region |
| Table | ✅ | ✅ | ⬜ | ⬜ | ARIA: table |
| DataTable | ✅ | 🟡 | ✅ | ⬜ | APG · Grid |
| DescriptionList | ✅ | ✅ | ⬜ | ⬜ | HTML: dl |
Gaps: Catalyst ships Table + DescriptionList but not a sortable/paging
DataTable. Ark provides the @ark-ui/react/table primitive; Headless UI
leaves tables to userland.
| Component | UIKit | Catalyst | Ark UI | Headless UI | Primary spec |
|---|---|---|---|---|---|
| SidebarLayout | ✅ | ✅ | ⬜ | ⬜ | APG · Landmarks |
| StackedLayout | ✅ | ✅ | ⬜ | ⬜ | APG · Landmarks |
| AuthLayout | ✅ | ⬜ | ⬜ | ⬜ | - (marketing shell) |
Gaps: Catalyst ships the two dashboard shells (StackedLayout,
SidebarLayout) and omits a dedicated centred-auth variant. UIKit
bundles AuthLayout for the sign-in / onboarding surface.
- UIKit covers 45 discrete components, weighted heavily on feedback
(
Alert/Callout/Skeleton/EmptyState) and overlay primitives that neither Catalyst nor Headless UI ship out of the box. - Catalyst is the closest chrome-level peer (dashboard shells, data
density primitives, paired
Field+Descriptioninputs) but skips feedback + overlay extras. - Ark UI is the deepest primitive-provider; UIKit reuses its machines
under the hood for
Combobox,Listbox,Pagination,Switch,FormStepper,Toast,Tooltip,Modal. - Headless UI covers the classic interaction primitives but skips structural and feedback components - it composes upward into frameworks rather than presenting an opinionated kit.
Update cadence: re-review each minor release of the upstream libraries, or whenever UIKit adds a layer beyond the eight listed above.