shadcn/ui が Base UI に切り替わりました。コードで実際に変わることはこれです
shadcn/ui のデフォルトが Radix から Base UI に変わりました。ぶつかることになる API の変更のすべて、-b radix という逃げ道、そして痛くない移行の順番。
Preet Suthar · · 5分で読めます
- React
- shadcn/ui
- Base UI
- Radix
2026 年 7 月 3 日、npx shadcn init は Radix ではなく Base UI を選ぶようになりました。見出しだけを読んだなら、おそらく二つのうちどちらかを考えているでしょう。Radix は死んだ、あるいは何も変わっていない。どちらも正しくありません。
私は Base UI 上に作られた shadcn/ui レジストリの HextaUI をメンテナンスしているので、今年の大半を両方のプリミティブ層の中で過ごしました。これは 7 月にあってほしかったガイドです。何が変わり、何が変わらなかったか、ぶつかることになる API の違いのすべて、そして移行すると決めた場合の順番です。
何が変わったか、一段落で
新しい shadcn/ui プロジェクトには Base UI のプリミティブが入ります。Radix も引き続き完全にサポートされます。shadcn チームによれば、Base UI にしか存在しないコンポーネントを除き、すべての更新と新しいコンポーネントは両方のライブラリ向けに出荷されます。既存のプロジェクトには影響ありません。新規プロジェクトで Radix を使いたければ、フラグを一つ渡します:
init を非対話で呼び、Radix を前提にしている CI やスクリプトがあるなら、新しいチェックアウトに驚かされる前に、いまそのフラグを追加してください。
なぜデフォルトが変わったのか
理由は二つ挙げられました。Base UI が安定版 1.6.0 に達し、週間ダウンロードが 600 万を超えていたこと、そして shadcn/create で作られたプロジェクトがすでに Radix より Base UI をおよそ 2 対 1 で選んでいたことです。デフォルトは人々の選択に従いました。
Base UI は Radix、Material UI、Floating UI を作った人たちによるもので、その系譜がはっきり出ています。Combobox、Autocomplete、Number Field、Toast、Preview Card など、Radix が出さなかったプリミティブもカバーしています。2026 年 9 月時点のバージョンは 1.8.0 です。
既存のアプリを移行すべきか?
おそらく今四半期ではなく、一度にでもありません。
アプリが安定していて、足りないプリミティブで困っておらず、チームの誰にも具体的な不満がないなら、Radix に留まってください。依存しているものがなくなることはありません。
二つ目のライブラリに手を伸ばさずに Combobox や Number Field が必要な場合、どのみち Tailwind v4 向けにコンポーネントを書き直している最中の場合、あるいは新しい shadcn/ui コンポーネントが最初に対象とする層にいたい場合は、移行してください。
どちらにしても、決める前に次のセクションを読んでください。違いは見た目だけのものではありません。
実際にぶつかる API の違いのすべて
これらは失敗の仕方で分類しました。最初のグループはビルドを壊します。二つ目のグループは問題なくコンパイルが通り、挙動が静かに変わります。こちらのほうがたちが悪いです。
ビルドが壊れる変更
asChild は render になる。 誰もが最初に出会うのがこれです。
render prop は要素か関数を受け取ります。関数形式では状態が渡されるので、開いているときにアイコンが変わるトリガーのようなものに便利です。
アンカー付きのポップアップに Positioner が加わる。 Menu、Select、Popover、Tooltip は Portal > Content から Portal > Positioner > Popup になります。Dialog に Positioner はなく、Backdrop と Popup を使います。
Overlay は Backdrop になる。 リネームして次へ進みます。
Select の値は null になりうる。 制御された Select が持つのは string ではなく Value | null です。useState<string>("") は useState<string | null>(null) になり、値を文字列として読んでいたすべての箇所にガードが必要です。
Accordion と Toggle Group の値は常に配列になる。 single モードでも value="a" は value={["a"]} になります。Tabs は単一の値のままです。
onOpenChange に第二引数が付く。 Radix では event.preventDefault() を呼んで閉じるのを止めます。Base UI は (open, details) を渡し、details.cancel() を呼びます。details.reason フィールドで、Escape キーだったのか、外側の押下だったのか、それ以外かがわかるので、「未保存の変更があります」ダイアログで便利です。
開いた状態のセレクターが変わる。 data-[state=open]: のバリアントは data-open: になります。これは className の文字列や cva のバリアントの中に隠れているので、移行完了と言う前に data-[state= を grep してください。
静かな挙動の変更
Tabs はデフォルトで手動アクティベーションになる。 Radix では矢印キーでフォーカスが移動し、同時にタブがアクティブになります。Base UI では矢印キーでフォーカスが移動し、Enter か Space を押してアクティブにします。テストやユーザーが Radix の挙動を期待しているなら、リストに activateOnFocus を設定してください。
チェックボックスとラジオのメニュー項目はメニューを開いたままにする。 CheckboxItem と RadioItem では closeOnClick のデフォルトが false です。通常の項目は従来どおり閉じます。こちらのほうが良いデフォルトだとは言えますが、ユーザーが気づく変更です。
ナビゲーションメニューが速く開く。 Base UI のホバー delay のデフォルトは 50ms です。Radix の delayDuration のデフォルトは 200ms でした。速いメニューは気持ちいいのですが、誰かがヘッダーをマウスで横切ったときに三つのパネルが立て続けに開きます。調整してください。
痛くない移行の順番
両方のライブラリをインストールしたままにします。コミットごとにコンポーネントを一つ移します。その都度テストを実行します。順番はこうです:
- ポップアップのない末端のコンポーネント: Switch、Checkbox、Slider、Toggle、Progress。ほとんどはリネーム作業です。
- Tabs と Accordion。 配列の値を直し、
activateOnFocusをどうするか決めます。 - Dialog と Alert Dialog。 話をややこしくする Positioner がないここで、
BackdropとPopupの構造とdetails.cancel()のパターンを覚えます。 - Popover と Tooltip。
Positionerを追加します。 - Select、Combobox、Dropdown Menu、Context Menu。 null になりうる値、
closeOnClick、そしてポップアップツリー全体。これらは最後に、最も多くのテストとともにやります。
コンポーネントを Base UI 版に置き換えるのは CLI コマンド一つで、ソースは git にあるので、信用せずに diff をレビューしてください:
それから git diff components/ui/dialog.tsx を実行し、残す前にすべての行を読んでください。
私ならやらないこと
ツリー全体に codemod をかけて祈る、ということはしません。ビルドを壊す変更は見つけやすいものです。静かな変更はそうではなく、設定ページでタブを切り替えるのにキー操作が二回必要になったことを codemod は教えてくれません。
プリミティブ層の切り替えとコンポーネントの再設計を同じ PR でやることもしません。shadcn/ui の要点はコードを自分が所有することです。所有するとは diff を読むことです。
移行を代わりにやってほしい場合
HextaUI は shadcn/ui プロジェクトに追加するレジストリです。すべてのコンポーネントがすでに Base UI で書かれていて、shadcn/ui の名前と props を維持し、同じテーマトークンを使うので、npx shadcn@latest add https://hextaui.com/r/dialog.json --overwrite で Base UI の Dialog が components/ui の他のファイルの隣に入ります。コンポーネントは MIT で無料です。HextaUI と shadcn/ui の比較ページに、何が違うのか、素の shadcn/ui のほうが良い選択になるのはどんなときかをまとめています。
よくある質問
Radix は非推奨ですか? いいえ。shadcn/ui はすべてのコンポーネントを両方のライブラリ向けに提供していて、チーム自身もまだ本番で Radix を使っています。
一つのプロジェクトで Radix と Base UI のコンポーネントを混ぜられますか? はい。移行中は両方の依存関係を抱えます。多くのプロジェクトは長い間混在したままになりますが、それで問題ありません。
テーマトークンを変える必要はありますか? いいえ。--background、--primary、--radius などは変わりません。プリミティブ層は Tailwind 側から独立しています。
Base UI は React Server Components に対応していますか? Base UI のプリミティブは Radix と同じくクライアントコンポーネントです。"use client" ディレクティブは shadcn/ui が置いた場所にそのまま残してください。
公式の変更履歴はどこにありますか? 2026 年 7 月のエントリは ui.shadcn.com/docs/changelog/2026-07-base-ui-default にあります。