React コンポーネントライブラリ 調査/選定メモ
個人的結論
headless を選ぶなら
- Radix UI + linaria or emotion
UI library を選ぶなら
- Mantine + emotion
ツールレベルなら UI library で十分に思うが、プロダクトレベルであれば先々見越してheadless 選んで移植性は高めに保つかなという個人的見解(スピード感にもよると思うが)
パフォーマンスを気にするものなら、headless + ゼロランタイムCSS in JS or CSS Modules を選ぶ
2023/4時点
前提/選定基準
個人で開発するフロントエンドアプリ(Gihub&GitlabのPR/MRビューアー的なツール)と、中規模プロダクト(Next.js使用予定)で使用する予定
- TypeScript
- React 18対応
- Vite対応
- a11y
- メンテナンス体制
- カスタマイズ性(出だしはそこまで必要ないが、将来的には必要になる可能性はある)
- ポータビリティ(移植性)
※ちゃんと言語化していなかったが、以下が近いので参考にさせて頂いた
調査:UIライブラリとStyleツールを検討する - 背景/選定ポイント
雑に Stiches いいな、Next UI いいな 思っていたが、以下を見てちょっとリスクがあると感じたので、真面目に選ぶことにした。(Next UI は v1正式リリースしていないのに、v2でStichesからTailwindCSSに乗り換えると)
CSS に関しての考え
- ガチガチにパフォーマンスを気にしないといけないようなものでもないため、開発者体験優先で、CSS in JS > CSS Modlues。
- (勝手な個人的こだわり) CSS in JS では、素のCSSがそのまま使える物が良い
- 暗記していないのでググってコピッてきたものを書き換えるのが地味に手間
- いざというとき CSS Modules への切り替えもしやすい
- 候補兼順位は linaria > emotion > styled-components
- Zero-Runtimeの方がパフォーマンス的に良いので、使えるなら linaria (絶対ではない emotionでも許容)
- 使い勝手やパフォーマンスや移植性的に emotion > styled-components
- Zero-Runtime で macaron というのが出ているが、パッと見は素のCSSで書けなそう&出たばかり(2022/12)なので今回は除外
- Tailwind CSSは使う気がない。常に触れ続ける&覚えるなら使うメリットは大きいと思うが、そうでなければ学習コストがネックになるので避けている。
Best React component libraries
共通事項
- アクセシビリティ必須
- カスタマイズ可能なスタイル
一覧
- Unstyled components(Headless components)
- Fully styled components (UI library)
refs:
Headless components vs UI library
UI library を使う方が良いケース:
- コンポーネントのカスタマイズにあまり労力をかけずに、ほとんどの要件を満たすことができると感じたら
Headless components を使う方が良いケース:
- ユニークな機能とカスタムデザインを持つデザインシステムを構築することが分かっている場合
UI libraryよりもHeadless componentsを使うことで、製品を非常に早く出荷する必要がある場合に足かせになるかもしれないということはない模様。
- UI libraryから
<Autocomplete />
(入力時にリアルタイムで候補を表示する入力コンポーネント)をレンダリングするのはシンプルでより直感的 - しかし、Headless componentsの経験から言うと、Headless componentsを使用して同じコンポーネントを実装しても、それほど時間はかからず、長い目で見ればはるかに多くのものを得ることができる
とのこと。
非常にユニークな機能性とデザインをサポートする必要がある場合、それらをUI libraryで実装することは価値がない。とのこと
Radix
Radix Primitivesは、アクセシビリティ、カスタマイズ、開発者の体験に重点を置いた低レベルのUIコンポーネントライブラリです。これらのコンポーネントは、デザインシステムのベースレイヤーとして使用することも、インクリメンタルに採用することも可能です。
Vision
アコーディオン、チェックボックス、コンボボックス、ダイアログ、ドロップダウン、セレクト、スライダー、ツールチップといった一般的なUIパターンについては、ほとんどの人が同様の定義を共有しています。これらのUIパターンはWAI-ARIAによって文書化され、コミュニティによって一般的に理解されています。
しかし、Webプラットフォームから提供される実装は不十分です。存在しないか、機能が不足しているか、十分なカスタマイズができないかのいずれかである。
そのため、開発者はカスタムコンポーネントを作ることを余儀なくされます。これは非常に難しい作業です。その結果、ウェブ上のほとんどのコンポーネントは、アクセスしにくく、パフォーマンスが低く、重要な機能が欠けています。
私たちの目標は、アクセシブルなデザインシステムを構築するためにコミュニティが使用できる、資金力のあるオープンソースのコンポーネントライブラリーを作ることです。
Styling
- className propを受け入れる
- data-state属性を対象とすることで、コンポーネントの状態をスタイル設定可能
- 任意のCSS-in-JSライブラリを使用可能
参考
Reach UI
各コンポーネントは、Safari+VoiceOver、Firefox+NVDA、およびEdge+JAWSでテストされています。プロジェクトが成熟するにつれて、WebAIMによる監査を受け、Reach UIを選択した場合、アプリにアクセス可能な強固な基盤があることを確認します。
Styling
コンポーネントがそのまま使えるように、基本的なスタイルが用意されていますが、stylesheets, styled components, emotion, glamorなど、好きなものを上書きして追加することが可能
= 任意のCSS-in-JSライブラリを使用可能?
Headless UI
Tailwind CSSと美しく統合するために設計された、完全にスタイルがなく、完全にアクセス可能なUIコンポーネントです。
= Tailwind CSS 前提
Vue もサポートしている
Reakit
ReactでアクセシブルなリッチWebアプリを構築する
Composition
Reakitは、Compositionを念頭に置いて作られています。実際、独自のコンポーネントは、Role、Tabbable、Compositeといった他のいくつかの抽象的なものによって構成されています。
Accessibility
ReakitはWAI-ARIA 1.1規格に厳密に準拠しており、ボタン、ダイアログ、タブなど、WAI-ARIA Authoring Practices 1.1に記述されている多くのウィジェットを提供しています。
Styling
ReakitはCSSライブラリに依存しない。コンポーネントは既定でスタイル設定されていません。そのため、好きな方法を自由に使うことができる。各コンポーネントは、classNameとstyleを含むすべてのHTMLプロップを受け入れる単一のHTML要素を返します。
CSS Modules も CSS in JS も使える(恐らく任意の CSS in JS が使える?)。
Managing state
Reakitコンポーネントはほとんどステートレスであるため、状態を変更するにはプロップを渡す必要があります。
コンポーネント
Role、Tabbable、Composite といった独自のものがある
Base UI
Base Webは、Webプロダクトを開始し、進化させ、統一させるための基盤です。
Styling
Styletron (CSS in JS) が前提。(独自のコンポーネントでもStyletronの使用が推奨されている)
積極的にメンテナンスしているようには見えない。最終リリース:2019?。React 18 にもまだ対応していない?
Components
Base Webは、堅牢なコンポーネント群を箱から取り出して提供します。これらには、Datepickerのような複雑ですぐに使えるコンポーネントや、Layerのような低レベルのComposableプリミティブが含まれます。
コンポーネントは豊富な印象
Extensibility
Overrides APIと設定可能なThemesを通して、Base Webは極めて高いレベルのカスタマイズ性を提供します。あるコンポーネントを一箇所だけ変更したい場合でも、Base Webの上にデザインシステムを構築したい場合でも、私たちはオプションを用意しています。
Built-in accessibility
Base Webは、アクセシビリティを第一に考え、コンポーネントを構築しているため、重い腰を上げる必要がありません。
その他
React 18 未対応っぽい?
Chakra UI
Chakra UIは、Reactアプリケーションを構築するために必要なビルディングブロックを提供する、シンプルでモジュール化されたアクセス可能なコンポーネントライブラリです。
Styling
Style Props を提供
- Background Gradient API がある
- theming あり
その他
Styleは慣れれば開発速度出そうだが、学習コストはそれなりにありそう
慣れても、他へのつぶしがあまり利かないのがネック
Material UI (MUI)
言わずもがな、マテリアルデザイン UI
Styling
sx prop で行う形になる?
デフォルトのスタイルライブラリはemotion、styled-componentsも選べるがSSRができない模様
その他
見栄えは良いが、学習コストは他より高い印象
Mantine
完全な機能を持つアクセシブルなWebアプリケーションをこれまで以上に速く構築する - Mantineには100以上のカスタマイズ可能なコンポーネントと50以上のフックが含まれており、あらゆる状況であなたをサポートします。
Styling
Mantineはemotionをベースにしたcss-in-jsライブラリで構築されています。
→ emotion がそのまま使える感じ。 = 移植もしやすい
→訂正。emotionがそのまま使えるは、emotion の styled component だけな模様。
それ以外で、素のCSSは指定できず、オブジェクト形式での指定のみっぽい。
style props 等、指定方法が豊富な印象
アプリケーションの残りの部分のスタイルを作成するために createStyles を使用することをお勧めします
→ スタイル生成用のフックがある
依存ライブラリ
- emotion
- Radix UI
その他
React 18 では 一部バグが残っているらしい
Geist UI
Geist UIは、Vercelデザインシステムを起源とするGeekスタイルのエレガントで美しいReactコンポーネントライブラリです。
テキストレイアウト、明暗線の最適化、スケールコンポーネントなど、Geist独自の優位性を活かして、クリーンでパワフルなパーソナルサイトを簡単に作成したり、カスタマイズ性の高いデザインシステムに基づいてモダンなウェブアプリケーションを素早く構築することができます。
Bundle Size
最近のクライアントアプリケーションのサイズを比較すると良いスコアであり、アプリケーションのパフォーマンスに影響を与えることはないでしょう。
バンドルサイズは他と比べると小さめ。その分提供しているコンポーネント等が少ない印象
Styling
上書きは、className と style props だけな模様
その他
他と比べたら、軽量&機能もシンプルというか最小限提供が売りっぽそう
Headless 提供コンポーネント比較
△:実験的orベータ
Radix UI | Reach UI | Headless UI | Reakit | 備考 | |
---|---|---|---|---|---|
Accordion | 〇 | 〇 | |||
Alert | 〇 | ||||
AlertDialog | 〇 | 〇 | |||
Aspect Ratio | 〇 | ||||
Avatar | 〇 | ||||
Button | 〇 | ||||
Checkbox | 〇 | ||||
Collapsible | 〇 | ||||
Combobox | 〇 | 〇 | 〇 | ||
ContextMenu | 〇 | ||||
Dialog (Modal) | 〇 | 〇 | 〇 | 〇 | |
Disclosure | 〇 | 〇 | 〇 | ||
Form | △ | △ | |||
Grid | △ | ||||
Group | 〇 | ||||
HoverCard | 〇 | ||||
Label | 〇 | ||||
ListBox (Select) | 〇 | 〇 | 〇 | ||
Menu (Dropdown) | ※ | 〇 | 〇 | 〇 | ※ハンバーガーメニュー式? |
NavigationMenu | 〇 | ||||
Popover | 〇 | 〇 | 〇 | ||
Portal | 〇 | 〇 | 〇 | ||
Progress | 〇 | ||||
RadioGroup | 〇 | 〇 | 〇 | ||
ScrollArea | 〇 | ||||
SkipNav | 〇 | スクリーンリーダーやキーボード操作時非表示 | |||
Separator | 〇 | 〇 | |||
Slider | 〇 | 〇 | |||
Switch (Toggle) | 〇 | 〇 | |||
Tabs | 〇 | 〇 | 〇 | 〇 | |
Toast | 〇 | ||||
Toggle Button | 〇 | ||||
Toggle Group | 〇 | ||||
Toolbar | 〇 | 〇 | |||
Tooltip | 〇 | 〇 | 〇 | ||
Transition | 〇 | ||||
VisuallyHidden | 〇 | 〇 | 〇 |
独自?のもの
- Radix UI
- Accessible Icon
- Direction Provider
- Slot
- Reach UI
- Auto ID
- Rect
- Windows Size
- Reakit
- Role
- Clickable
- Composite
- Id △
- Tabbable
個人的には、 Radix UI 一択
UI library 選定
※コンポーネント数は多いので比較はやめておく…(どれ選んでも足りなきゃ作る
以下は除外
- Base UI : メンテナンスに懸念しかない
- Chakura UI: Tailwind CSS 前提が個人的にネック
- Geist UI: Styling方法が個人的にネック、種類も他より少なめ
選択肢は MUI か Mantine。
- (ドキュメントの見みやすさの問題かもしれないが) MUI の方が学習コスト高そうに見える
- Mantine には、便利そうな hooks が用意されていて魅力
- UIの見栄え/分かりやすさを重視するならMUI一択だが、今回はそこまで
- どうしても独自コンポーネントを用意する必要ができた場合に、デザインを合わせる手間は、デザインがシンプルな分 Mantine の方が少ないと思われる
- ※Mantine が Radix UI に依存してるのでRadix UIに何かあれば注視する必要はあるかもしれない