Cloud Parts

UI libraries

Reusable interface parts: styled components you drop in and theme, or headless ones that handle state, keyboard and accessibility while you write the markup and styles.

2 technologies on this page ↓

How it works

Most apps need the same parts: buttons, dialogs, menus, comboboxes, date pickers, data tables. Each part has two layers. The behaviour layer holds state (is the menu open, which row is selected, how the rows are sorted) and the interaction rules, such as the roles and keys the W3C’s ARIA Authoring Practices Guide sets out for each widget: in a combobox, Down Arrow moves into the popup and Escape closes it. The presentation layer is the markup and CSS. A component library ships both layers and implements one design system: Material UI renders Google’s Material Design, and you adjust it through a theme object (colours, spacing, shape) rather than rewriting its CSS. A headless library ships only the behaviour. TanStack Table hands you header groups and sorted rows and renders nothing; Radix Primitives, Headless UI, React Aria and Base UI render unstyled, accessible parts that you style with Tailwind, CSS Modules or plain CSS. A third route, shadcn/ui, copies styled component source into your repository instead of installing it as a package, with headless parts underneath. The trade is speed against control: a component library looks finished on day one but fights a design that differs from its own, while a headless one fits any design and leaves every element and style to you.

Think of it as

Furniture. A component library is a showroom set: sofa, table and chairs that match and arrive assembled, in the maker’s style. A headless library is the hardware: hinges, drawer runners and locks that work smoothly, fitted into cabinets you design yourself.

Reach for it when

  • Internal tools and admin screens where shipping fast matters more than a distinctive look: a component library
  • A product with its own design system: build it on headless parts so you own the markup and styles
  • Widgets whose keyboard and screen reader behaviour is easy to get wrong by hand, such as comboboxes, menus, dialogs and data grids
  • One behaviour across several frameworks: TanStack Table’s core has adapters for React, Vue, Solid, Svelte, Angular and five more

Think twice when

  • Restyling a component library far away from its design system; MUI’s own team writes that Material UI “can become unwieldy” when a design diverges significantly
  • A quick prototype on a headless library: you write and style every element yourself
  • Mixing several component libraries in one app; shadcn/ui’s docs describe the usual result as wrapped components, style workarounds and incompatible APIs

A real example

A team needs an orders table with sorting, filtering and pagination. With a component library’s data grid they pass rows and columns and have a finished grid in an afternoon, though in MUI X multi-column sorting and column pinning sit in the paid Pro package and row grouping in Premium. With TanStack Table they register the sorting, filtering and pagination features, then render their own <table> with the design system’s classes. It takes more code, but the table matches every other screen, and the same sorted rows can drive a card list on mobile.

Kinds of ui libraries

Specific products, and what each does differently.

Three ways to get components#

What you install, and what is left for you to write.

Component libraryHeadless libraryCopy-in components
ExamplesMaterial UI, BootstrapTanStack Table and Form, Radix Primitives, Headless UI, React Aria, Base UIshadcn/ui
What you getStyled components and a themeState, logic and accessible behaviour; some ship unstyled parts, some only functions and stateThe source of styled components, added to your repository
Markup and CSSWritten by the library; you theme and override itWritten by youWritten by the tool, then owned and edited by you
Fixes and upgradesUpgrade the package, including its breaking major versionsUpgrade the package; your markup is untouchedThe headless layer updates as a dependency; the copied top layer is yours to merge
Fits bestInternal tools, prototypes, apps that can follow the library’s design systemProducts with their own design systemTeams that want a styled start and full control afterwards

In code · ts

// npm install @tanstack/table-core@9
import {
  constructTable,
  createSortedRowModel,
  rowSortingFeature,
  sortFns,
  tableFeatures,
  type ColumnDef,
} from '@tanstack/table-core'
import { storeReactivityBindings } from '@tanstack/table-core/store-reactivity-bindings'

type Order = { id: string; customer: string; total: number }

const data: Order[] = [
  { id: 'A-1', customer: 'Ada', total: 120 },
  { id: 'A-2', customer: 'Linus', total: 45 },
  { id: 'A-3', customer: 'Grace', total: 310 },
]

// the headless library holds the state and the sorting logic
const features = tableFeatures({
  coreReactivityFeature: storeReactivityBindings(),
  rowSortingFeature,
  sortedRowModel: createSortedRowModel(),
  sortFns,
})

const columns: ColumnDef<typeof features, Order>[] = [
  { accessorKey: 'id', header: 'Order' },
  { accessorKey: 'customer', header: 'Customer' },
  { accessorKey: 'total', header: 'Total' },
]

const table = constructTable({ features, columns, data })

// what a click on the “Total” header would call
table.getColumn('total')!.toggleSorting(true) // descending

// the markup is yours: here, plain text lines instead of <tr> elements
for (const row of table.getRowModel().rows) {
  console.log(row.getAllCells().map((cell) => cell.getValue()).join('  '))
}
// A-3  Grace  310
// A-1  Ada  120
// A-2  Linus  45

Often confused with

Where it came from2011–2026

Bootstrap set the pattern for component libraries. Two Twitter employees (@mdo and @fat) built it in mid-2010 as Twitter Blueprint, and it served as the company’s style guide for internal tools for over a year before its public release on 19 August 2011. In 2014 Material UI started as a React implementation of Google’s Material Design guidelines. Both gave teams one design language with ready-made parts, and both grew into some of the most widely used front-end projects.

Ready-made parts are hard to bend. In one MUI developer survey, five times as many developers as the year before were struggling to customize the components, and customization became the focus of Material UI v5. In June 2018 Merrick Christensen had described the other answer: a headless user interface component “offers maximum visual flexibility by providing no interface”. React Table v7 (March 2020) was rebuilt on that idea as a hooks-only utility that renders nothing.

Headless libraries for accessible widgets followed: Radix Primitives, Headless UI, React Aria, and in 2022 MUI Base (now Base UI), MUI’s headless alternative to its own library. shadcn/ui then combined the two models by copying styled component source, built on headless parts, into each project, citing AI models that read and improve the code as one more reason to own it.

Why it’s built this way

Separate behaviour from presentation
React Table v7’s release notes gave three reasons: the look of a table belongs to the app, dropping UI options removes a huge API surface to maintain, and an app can extend a design the library never imagined.
Follow the WAI-ARIA patterns
The W3C’s Authoring Practices Guide documents roles, states and keyboard rules for widgets such as comboboxes and menus. Libraries that implement them once save every app from re-deriving focus management and key handling.
A theme object instead of editing CSS
Material UI v1 moved from inline styles, which lacked media queries and pseudo-selectors, to CSS-in-JS with a JavaScript theme holding the palette, typography and breakpoints, so a brand could be applied in one place.
Ship source, not a package
shadcn/ui argues that installed libraries end in wrappers and style workarounds, so it hands you the component code to edit directly while the headless layer underneath still updates as a dependency.

Timeline

  1. 2011

    Twitter releases Bootstrap publicly on 19 August

  2. 2014

    Material UI starts as a React implementation of Material Design

  3. 2018

    Merrick Christensen’s “Headless User Interface Components”; Material UI v1

  4. 2020

    React Table v7 rebuilt as a headless, hooks-only utility

  5. 2022

    MUI announces MUI Base, a headless alternative to Material UI

  6. 2025

    Base UI 1.0 on 11 December

  7. 2026

    TanStack Table v9 with opt-in features and ten framework adapters

Sources13

Improve this page on GitHub