Control UI vs shadcn/ui
Both ship open-source React source through the shadcn CLI. The difference starts after install: a typed knob contract, skins that re-value it wholesale, and 16 skin modes audited against WCAG AA on every commit.
The short answer
Both install through the shadcn CLI, keep the same core token names, and leave MIT source in your repository. The difference starts one layer up. Control UI paints through typed CSS custom properties, so a single skin re-values the whole system at once, and CI re-checks all 16 skin modes against WCAG AA on every commit. shadcn/ui leaves paint and contrast to your team, and hands you a far larger pool of community recipes in return.
Both cover classic app UI. Choose on what you want to stop maintaining by hand, not on product type.
Side by side
| Control UI | shadcn/ui | |
|---|---|---|
| License | MIT, open source | MIT, open source |
| Install model | Registry manifests copy editable source into components/control-ui/* | CLI copies editable source into components/ui/* |
| Classic app UI | Forms, overlays, navigation, tables, sidebars — no chart, no carousel | Complete, chart and carousel included |
| Agent surfaces | Chat, composers, activity, context, tasks, citations | Not covered |
| Theming | Typed --cui-* knobs registered with @property, re-valued wholesale by a skin pack | Theme file with CSS variables consumed by Tailwind utilities |
| Visual restyling | Swap or layer a whole skin without touching component source | Edit tokens and component classes per component |
| Component anatomy | Stable data-control-* attributes that effects and extensions target | Not a stable public contract |
| Contrast | 16 skin modes re-checked against WCAG AA on every commit | No gate shipped |
| Motion | Duration/easing tokens with a reduced-motion kill switch | Per-component transitions |
| Community | Younger and smaller | The largest in the React ecosystem |
| Runtime coupling | None — components take plain props and children | None |
Numbers change monthly; architecture does not. The rows above describe structure, so they age slower than star counts or download charts would.
Where they align
The overlap is deliberate. Control UI follows shadcn conventions because they proved the right ownership model for UI source:
- Source lands in your repository — no versioned component package to fight at upgrade time.
- Core color tokens keep shadcn names like
--background,--primary, and--ring, so an existing theme seeds a Control UI skin instead of starting from zero. - Installation runs through the same
npx shadcn@latest addflow pointed at a registry URL.
A team can run both in one app without coordination: neither writes into the other's directories. See shadcn compatibility for the exact contract.
Where they differ
Scope. Both ship the surfaces every product needs — dialogs, dropdowns, forms, tables, sidebars. Control UI then extends into territory shadcn/ui does not address: streaming chat turns, prompt composers with attachment rails, collapsible agent activity, context-window graphs, task progress, and citation previews. Building those from base primitives is exactly the work agent teams repeat before writing their first feature. The trade runs the other way on charts and carousels, which shadcn/ui has and Control UI does not.
Restyling depth. With shadcn/ui, a redesign means editing class lists across installed components. Control UI separates paint from structure: components render through registered CSS custom properties, and a skin pack re-values the entire token contract — radius, color ramps, typography, bevels, even WebGL surfaces — while the component source stays untouched. One app can compile several skins and switch between them.
Anatomy stability. Control UI emits stable data-control-family and data-slot attributes, which is what lets
extensions like hover effects follow every control app-wide, including portalled surfaces. In shadcn/ui the rendered
markup is an implementation detail that changes with updates.
Ecosystem gravity. shadcn/ui wins this one outright: more contributors, more third-party examples, more Stack Overflow answers. Control UI's registry is younger and its community smaller. If your team relies on copying community recipes, weight that honestly.
Consistency that is checked, not assumed
Every component library claims a consistent design system. The question is what happens when someone re-values a color six months in. Control UI answers it with a gate instead of a guideline.
--cui-* knob is registered with @property: declared syntax, initial
value, inheritance. A bad value falls back to the declared initial instead of silently killing the paint, and
animatable knobs interpolate rather than snap.bun run validate walks all eight skin packs in light and
dark, resolving canonical theme colors and rendered anatomy alike — popup surfaces, badge borders, active tabs —
and fails the build if any of the 91 required checks drops below WCAG AA./r/contrast-anatomy.json and the full knob
surface as /r/skin-contract.json, so a coding agent can read what it is allowed to re-value before it edits
anything. See agent surface.One honest limit: the runner lives in this repository, not in your install, so a skin you write yourself is not audited automatically today. What you inherit is the shipped skins already clearing the bar and the published anatomy list to point your own checks at. Lock-in covers where that governance sits.
Which one to choose
Not by product type. A dashboard built on Control UI gets the same primitives plus the skin system and the contrast gate. Choose on these instead:
Running both is the common case, not a compromise. Many teams keep their existing components/ui/*, install Control
UI beside it, and adopt the agent surfaces first. Getting started covers both paths.
Frequently asked questions
- Is Control UI a replacement for shadcn/ui?
- It can be. Control UI covers the classic app surface — forms, overlays, navigation, tables, sidebars — so most projects could run on it alone; charts and carousels are the notable gaps. It is a separate registry rather than a fork, following shadcn conventions of CLI install, owned source, and compatible token names, so running both side by side stays a first-class option.
- Should I use shadcn/ui instead of Control UI for a dashboard or SaaS console?
- Not automatically. Both cover the primitives a dashboard needs, and Control UI adds a skin system and a contrast gate that re-checks 16 skin modes against WCAG AA on every commit. Pick shadcn/ui when you rely on its larger pool of community recipes, or when you need its chart and carousel components today.
- Can I use Control UI and shadcn/ui components in the same project?
- Yes. Both install as plain source under your own directories and share the core shadcn token vocabulary like --background and --primary. Neither writes into the other's files, so they coexist without coordination.
- Does Control UI require Tailwind CSS?
- The docs app is built with Tailwind v4 and installed components are styled for it, but painting happens through CSS custom properties (--cui-* knobs and theme tokens). Any setup that serves those variables can host the components.
- How do licensing and ownership differ?
- Both are MIT-licensed open source. Both copy source into your repository instead of shipping a versioned dependency package, so you own and edit every installed line either way.