# 3rd UI library
| Library | Animation / Transition | Accessibility (a11y) | Keyboard Support | Theming / Customization | Customizability | Components Count | TypeScript Friendliness | Community Activity & Maintenance | Bundle Size | Learning Curve | Applicable Scenarios / Notes |
|---------------------|--------------------------------------------|----------------------------|--------------------------|----------------------------------------|------------------|------------------|----------------------------------------|----------------------------------|-------------------|----------------|-------------------------------------------------------------|
| **shadcn/ui** | ✅ Integrated with Framer Motion | ✅ Based on Radix Primitives | ✅ Full focus management | ✅ Tailwind + CSS-in-JS hybrid | High | ~50+ | ✅ TS-first with auto-generated types | 🌟 Medium–High (Radix community) | Small (~10–20 KB) | Medium | Extensible by default, great for programmatic customization |
| **Radix UI** | ✅ CSS Transitions (e.g., Popover/Tooltip) | ✅ WCAG-compliant | ✅ Full focus management | ✏️ Headless, requires custom styling | Very High | ~30+ primitives | ✅ Fully typed | 🌟 High (officially maintained) | Small (~5 KB) | Low–Medium | Maximum flexibility for composing headless components |
| **Chakra UI** | ✅ Basic Motion | ✅ Complete ARIA support | ✅ Full keyboard support | ✅ Theming system + custom variables | Medium | ~60+ | ✅ Good TS support | 🌟 High (active community) | Medium (~25–30 KB)| Low | High productivity, rich default styling |
| **MUI (Material-UI)** | ✅ CSS Transitions / Motion | ✅ WCAG tools integrated | ✅ Full support | ✅ Highly customizable themes | Medium | ~100+ | ✅ TS-first | 🌟 High (very popular) | Medium (~40–50 KB)| Low | Quick to get started, rich set of built-in components |
| **Headless UI** | ✅ CSS Transitions (via `Transition` comp.)| ✅ Complete ARIA support | ✅ Full keyboard support | ✏️ Tailwind-based, requires custom styles| High | ~15+ | ✅ Good TS support | 🌟 Medium (official maintenance) | Small (~5 KB) | Low–Medium | Seamlessly integrates with Tailwind, logic-only components |
| **Ant Design** | ✅ CSS Animations | ✅ Complete ARIA support | ✅ Full support | ✅ Theming via Less variables | Medium | ~80+ | ✅ Has types, needs some reinforcement | 🌟 High (enterprise-level) | Large (~90 KB) | Medium | Commonly used for enterprise/ERP backoffice UIs |
| **Blueprint.js** | ✅ CSS Transitions & Minor Animations | ✅ Built-in ARIA roles | ✅ Full support | ✅ Sass variables + CSS overrides | Medium | ~50+ | ✅ TS-first (native TypeScript) | 🌟 Medium (maintained by Palantir)| Large (~60–70 KB) | Medium | Best for desktop-grade complex enterprise UIs |
## Vote
### Andy
**shadcn/ui** : Because the components themselves can be highly customized locally, they are suitable for designers to design
- Animation/Transition: 4
- Accessibility (a11y): 5
- Keyboard support: 4
- Theming / Customization: 5
- Customizability level: 5
- Components count: 3
- TypeScript support: 4
- Community & Maintenance: 4
- Bundle size: 5
- Test coverage: 5
- Others:
### Aaron
#### Option 1: Radix UI
Already try to migrate Avatar to Radix Base on my local, looks like is easy to migrate
Also could import by chunk/sub module
- Animation/Transition: 3
- Accessibility (a11y): 5
- Keyboard support: 5
- Theming / Customization: 5
- Customizability level: 5
- Components count: 3
- TypeScript support: 5
- Community & Maintenance: 5
- Bundle size: 5
- Test coverage: 5
- github star: 17.1k
- llm.text support: not support
#### Option 2: Ark UI
- Animation/Transition: 4
- Accessibility (a11y): 5
- Keyboard support: 5
- Theming / Customization: 5
- Customizability level: 5
- Components count: 3
- TypeScript support: 5
- Community & Maintenance: 5
- Bundle size: 5
- Test coverage: 5
- github start: 4.3K
- llm.text support: support
Other thought:
- Complex component like table, date picker we could follow current design to use other 3rd library. (react-date-picker, floating-ui, ...etc)
### Aaron Chen
I'd like to propose a guideline when implemenet a component:
- 最外層 component expose 出所有 sub component props, also its props type
- sub component 都要 export
#### expose sub component props to main component
```tsx
import * as React from "react";
import { Accordion } from "radix-ui"; // 假設 "radix-ui" 是您專案中 @radix-ui/react-accordion 的正確路徑
import classNames from "classnames";
import { ChevronDownIcon } from "@radix-ui/react-icons";
import "./styles.css";
const AccordionTrigger = React.forwardRef(
({ children, className, ...props }, forwardedRef) => (
<Accordion.Header className="AccordionHeader">
<Accordion.Trigger
className={classNames("AccordionTrigger", className)}
{...props} // 從 AccordionDemo 傳來的 AccordionTriggerProps 會被展開到這裡
ref={forwardedRef}
>
{children}
<ChevronDownIcon className="AccordionChevron" aria-hidden />
</Accordion.Trigger>
</Accordion.Header>
),
);
// 自訂的 AccordionContent 包裹元件
const AccordionContent = React.forwardRef(
({ children, className, ...props }, forwardedRef) => (
<Accordion.Content // Radix Accordion.Content 元件
className={classNames("AccordionContent", className)} // 合併外部傳入的 className
{...props} // 從 AccordionDemo 傳來的 AccordionContentProps 會被展開到這裡
ref={forwardedRef}
>
<div className="AccordionContentText">{children}</div>
</Accordion.Content>
),
);
// 修改後的 AccordionDemo 元件,使用新的 props 命名
const AccordionDemo = ({
// Accordion.Root 的行為控制 props
type = "single",
defaultValue = "item-1",
collapsible = true,
// 用於傳遞給子元件的 props,名稱已對齊元件名
rootProps,
AccordionItemProps, // 替換了 commonItemProps
AccordionTriggerProps, // 替換了 commonTriggerProps
AccordionContentProps, // 用於所有內容區域
}) => (
<Accordion.Root
className="AccordionRoot"
type={type}
defaultValue={defaultValue}
collapsible={collapsible}
{...rootProps}
>
<Accordion.Item
className="AccordionItem"
value="item-1"
{...AccordionItemProps} // 應用於 Accordion.Item
>
<AccordionTrigger {...AccordionTriggerProps}>Is it accessible?</AccordionTrigger>
{/* 自訂的 AccordionContent 包裹元件接收 AccordionContentProps */}
<AccordionContent {...AccordionContentProps}>
Yes. It adheres to the WAI-ARIA design pattern.
</AccordionContent>
</Accordion.Item>
<Accordion.Item
className="AccordionItem"
value="item-2"
{...AccordionItemProps}
>
<AccordionTrigger {...AccordionTriggerProps}>Is it unstyled?</AccordionTrigger>
<AccordionContent {...AccordionContentProps}>
Yes. It's unstyled by default, giving you freedom over the look and
feel.
</AccordionContent>
</Accordion.Item>
<Accordion.Item
className="AccordionItem"
value="item-3"
{...AccordionItemProps}
>
<AccordionTrigger {...AccordionTriggerProps}>Can it be animated?</AccordionTrigger>
{/* Item-3 直接使用 Radix Accordion.Content。
AccordionContentProps 也會直接應用於此。
原有的 className="AccordionContent" 會與 AccordionContentProps 中可能存在的 className 合併。
*/}
<Accordion.Content
className="AccordionContent" // 這是 item-3 原本的 className
{...AccordionContentProps} // 應用 AccordionContentProps
>
<div className="AccordionContentText">
Yes! You can animate the Accordion with CSS or JavaScript.
</div>
</Accordion.Content>
</Accordion.Item>
</Accordion.Root>
);
export default AccordionDemo;
```
## Radix UI
**Animation/Transition: 4**
**Accessibility: 5**
**Keyboard support: 5**
**Theming / Customization: 5**
**Customizability level: 5**
**Components count: 3**
**Maintenance: 5**
**Bundle size: 5**
https://base-ui.com/react/components/