Framework-agnostic UI is not a design system
“Framework-agnostic” is doing too much work in this category.
People searching it usually want one of two products. They are not the same product.
Two problems
Section titled “Two problems”1. Widget portability I want a Dialog (or Checkbox, or Combobox) that works in React, Vue, and Angular. Same DOM. Same ARIA. Same keyboard map. Same theming hooks. One implementation, several bindings.
2. Design-system portability I want one look and one layout language across products. React this year. Angular in the other app. HTML in a marketing page. An agent emitting screens next quarter. The brand should not fork.
A kit that solves (1) can still leave you with five design systems. A CSS contract that solves (2) will not give you a shared JS keyboard map.
What widget kits actually share
Section titled “What widget kits actually share”They share implementation.
That is valuable when the hard part is behaviour: typeahead, focus trap, disabled dates, virtualised lists. Native HTML does not cover it. You want one well-tested primitive and thin wrappers.
The cost is the component model. You adopt their DOM, their props, their theming API, their versioning. The design system becomes “whatever that kit looks like when we theme it.” Page layout is still ad hoc. Tokens may or may not match Figma. Angular and React stay consistent only where you used their widgets.
Airframe is not racing that. If you need that Dialog, use it. Put it on a visual contract. Do not ask it to be the contract.
What a design system needs to share
Section titled “What a design system needs to share”Not the widget class. The invariants.
| Invariant | Typical home |
|---|---|
| Colour, space, type, radius, motion | Tokens |
| Page structure | Layout grammar (stack, inline, grid) |
| Button / card / input look | Patterns or wrappers over those patterns |
| Focus, contrast, reduced motion defaults | Tokenised CSS, not a React context |
| How agents are allowed to name things | Rules and a class reference |
Those can live in CSS. Then every engine is a consumer.
Your design system
│
CSS contract (tokens, layouts, patterns)
│
Angular · React · Vue · HTML · AIThe markup is the design intent. Framework files only bind.
<header class="af-inline af-justify-between">
<h1>Team</h1>
<button class="af-btn">Invite</button>
</header>React uses className. Angular uses class. Vue uses class. There is no @airframeui/react. That absence is the architecture. How to keep one design system across React and Angular.
CSS-only is a tradeoff. Say it.
Section titled “CSS-only is a tradeoff. Say it.”Airframe ships 57 CSS patterns. Behaviour is native HTML: <button>, <dialog>, <details>, form controls.
That means:
- You get the same look without a JS runtime.
- You do not get “the same keyboard map” for a menu in every framework from
@airframeui/core. - Toasts, comboboxes, and rich overlays still need kit JS or a primitive library.
Teams that wanted a portable component will bounce if the site pretends otherwise. Teams that wanted a portable design system will bounce if you ship three framework packages and call that the product.
Separate design from behaviour.
Where shadcn fits
Section titled “Where shadcn fits”shadcn is a distribution model: own the React source in your repo. Often on Radix, Base UI, or React Aria.
That is still problem (1), in one engine, with a better ownership story. It does not give Angular a shared grammar. You can wrap af-btn inside a shadcn-style file. Airframe and shadcn.
Where Tailwind and Bootstrap fit
Section titled “Where Tailwind and Bootstrap fit”Tailwind shares utilities. The design system is whatever you compose this week. Two apps will not compose the same way.
Bootstrap shares components in CSS (and some JS). Closer to a look. The layout language is still mixed utilities and components, and the brand is Bootstrap until you override it.
Airframe starts with structure: named layout, tokens, patterns. Comparison: Airframe vs Bootstrap vs Tailwind.
Use as much as you need
Section titled “Use as much as you need”You can take tokens and ignore patterns. You can take layouts and keep your own buttons. You can wrap af-btn and never see a class in product templates.
You cannot take a three-framework widget kit and assume the design system problem is solved. You also cannot take Airframe and assume the combobox problem is solved.
One source of look. One grammar. Engines and behaviour libraries stay swappable. Use as much as you need.
Next steps
Section titled “Next steps”- One UI language. Everywhere. — the customer promise and the CSS layer.
- Design tokens as the source of truth — git, CSS, Figma (export on the roadmap).
- Framework support — install the same CSS in each engine.