Product and “headless” systems: Polaris, Primer, Radix, shadcn/ui, Tailwind
Why:You’ll see that an interface part has four layers (structure, behavior, accessibility, look) and that different systems take on different numbers of them. Afterwards you can explain how Radix differs from Polaris, and build utility classes from your own tokens, as in Tailwind.
30 minutes
Read by speech synthesis (Qwen3-TTS); the voice is not a person’s.
Headless components give an interface part behavior and accessibility but no styling, as in Radix. Polaris, Primer, shadcn/ui and Tailwind take other layers.
An interface part, cut into layers
Take a modal window. What does it need to be a good one?
- Structure: the markup of the window, a heading, a close button.
- Behavior: it opens on a press, closes on Esc and on a click outside it, keeps focus inside, and gives focus back to the button.
- Accessibility: a screen reader announces the window, and the background isn’t read out.
- Look: colors, corners, a shadow, an animation.
A beginner thinks about the fourth, but the difficulties lie in the first three: they are hard to get right even by hand. That’s why systems differ in how many layers they take on. Choose an approach on the diagram and see what is left for you.
| Structure | Behavior | Accessibility | Look |
|---|---|---|---|
| ready | ready | ready | you write it |
Plain HTML (dialog, details). The browser knows how to open and close, how to trap focus and what to tell a screen reader. You write the look.
The price of the choice. The behavior is limited to what the browser can do.
Check yourself: what four layers does an interface part have?
Structure, behavior, accessibility and look.
Product systems: Polaris and Primer
Polaris is Shopify’s system for the interface of a shop’s admin, and Primer is GitHub’s system. Both are made for the company’s own products, and that is both their strength and their weakness.
The strength: they answer in detail the question “how do you build working screens”: lists and details, tables, settings forms. The examples are visible and alive: millions of people use them.
The weakness: outside their own platform they travel badly. Polaris now rests on web components for apps that are embedded in Shopify’s admin. And Primer at GitHub has two faces: Product UI for the interface of the service itself, and Brand UI together with a Brand toolkit for marketing pages. This is an instructive split: an “interface you work in” and a “page that persuades” have different needs for density and air, and the systems for them should be different, or at least have different modes. Primer calls its tokens “primitives”: color, spacing and typography.
Shopify
- Idea
- The interface of a shop’s admin: clear operations on products, orders and customers.
- Tokens
- Foundations and tokens for Shopify apps; the system has moved to web components.
- Components
- Web components for apps that are embedded in the Shopify admin so as to look native there.
- Accessibility
- Accessibility is described together with the components.
- Openness
- The documentation is public (shopify.dev/docs/api/polaris).
- What to take
- Working admin screens: “list and details”.
- When not to take it
- Outside Shopify: the system is built as part of the platform and travels badly beyond it.
Open the system’s documentation (opens the system’s own site)
Headless: Radix and its relatives
Radix Primitives (a project of WorkOS) gives complex behaviors with no line of styling: an accordion, a dialog, a dropdown menu, tabs and others, each in its own package. Everything follows the WAI-ARIA guidelines, with keyboard control and focus management that are tested with screen readers. You write the look yourself, in CSS or in Tailwind.
Radix has relatives: Adobe’s React Aria and Headless UI. The idea is the same: do the hardest and most boring part (accessibility) once, and give it to everyone for free, and leave the styling to the authors.
But before a library, think about the platform. The browser can do a lot by itself: details opens a block, dialog holds focus and closes on Esc, the popover attribute gives a layer that pops up. All of these are already “headless” components, built into the language. If a task is solved by them, you need no library.
shadcn/ui: code you own
shadcn/ui calls itself “not a component library”: the components aren’t installed as a package but copied by a command straight into your project as source code. You get both the behavior and a starting look, and you can change anything without waiting for another library’s release. You pay by making the updates and fixes yourself. It’s an owner’s choice: “my code, my concern”. The source is open.
Tailwind: a system inside the markup
Tailwind CSS turns the usual order upside down. Instead of a ready component you get a vocabulary of short classes, and they are built on the tokens of a theme: p-4 is a spacing from the spacing scale, text-lg is a size from the type scale, bg-blue-600 is a color from the palette. In Tailwind the theme is described by CSS variables, and each variable produces utility classes.
The main property of such a system: by default you don’t write “17 pixels”, you take a value from the vocabulary. There’s an escape hatch (a value in square brackets, p-[17px]), but it stands out in the markup and counts as an exception. That’s the discipline of a design system, built into the very way of writing. The price: the markup grows classes, and accessibility is your responsibility. You already know tokens; in this lesson you’ll make a small vocabulary of utilities and see how it’s built inside.
Check yourself: how is shadcn/ui different from a library?
The components’ code is copied into your project and becomes yours: you’re free to change it, but you’ll have to fix it yourself.
How to choose
A rough rule:
- You need it fast and without character (an internal service): a ready-made system.
- You need a character of your own and complex widgets: headless components or shadcn/ui.
- You need only the look by rules: utilities.
- A simple site without complex widgets: plain HTML, your own tokens and components.
For your project it’s almost certainly the last. But it’s useful to know the others, because sites and builders that you’ll meet in the parts on AI are made from exactly these.
Practice
Build a mini Tailwind from your project’s tokens: eight utility classes and a page built from them alone. Notice how the rule for the look moves from one place (“this is what a card looks like”) into words (“it has spacing 4, a radius and the accent”).
What was wrong with 2014
In 2014 there was no limited vocabulary: everyone wrote sizes and colors as they liked, and pages drifted apart. Later it turned out that the constraints (“only these values are allowed”) were the most valuable thing in systems, and Tailwind, shadcn/ui and Radix are built on that discovery.
Practice
Preparing your page…
Test
Question 1 of 6
Cards
These cards go into your review once you finish the lesson.
What four layers does an interface part have?
Answer
Structure (the markup), behavior (how it opens, how focus moves), accessibility (ARIA, keyboard) and look. Approaches differ in how many layers they take on.
What are “headless” components?
Answer
Structure, behavior and accessibility are ready, and there is no styling: you write the look. Examples: Radix, React Aria, Headless UI.
How is shadcn/ui different from a library?
Answer
The components’ code is copied into your project by a command and becomes yours. You are free to change it, but you fix and update it yourself.
What is Tailwind as a system?
Answer
The tokens of the theme produce short classes (p-4, text-lg, bg-blue-600). By default you don’t write “17 pixels”: you take a value from the vocabulary, and the escape hatch in brackets counts as an exception.
What does plain HTML do in place of a library?
Answer
details opens a block, dialog holds focus and closes on Esc, the popover attribute gives a layer that pops up. First check whether a ready element exists.
Sources
- Shopify Polaris link only, in English
- Primer (GitHub) link only, in English
- Radix Primitives link only, in English
- shadcn/ui: documentation link only, in English
- Tailwind CSS: Theme variables link only, in English
- <dialog> (MDN) CC BY-SA, in English
Next
You now know: product and headless design systems.