AI 工具 22 min read

pick-ui-library 實測:20 個前端套件清單,6 情境抓到 2 個坑

pick-ui-library 是 Emil Kowalski 收在 MIT 授權 emilkowalski/skills 裡的 Claude Code skill,用 85 行清單把 19 種前端任務對到 20 個函式庫,要手打 /pick-ui-library 才載入。我跑 6 個情境,它會先看 package.json、不亂換依賴,但一次給了已棄用的套件名——清單值得用,安裝前自己核對 npm。

pick-ui-library 實測:20 個前端套件清單,6 情境抓到 2 個坑
本文目錄 · 10
懶人包
  • pick-ui-library 是 Emil Kowalski 收在 emilkowalski/skills(MIT)裡的一支 Claude Code skill,85 行,內容是一份 19 種前端任務對應 20 個函式庫的選型清單,2026-07-21 加入 repo。
  • 它設了 disable-model-invocation: true,要自己打 /pick-ui-library 才會載入。repo 在 2026-10-21 是 48.1k stars,這是 15 支 skill 共用的數字。
  • 我在 React 19 專案跑了 6 個情境:已裝 react-hot-toast 時,它照規則沿用、不硬換 Sonner;只打指令不帶問題時,只回一句固定開場白。
  • 實測抓到 2 個坑:清單只放連結、沒寫 npm 套件名,模型一次給了已棄用的 @base-ui-components/react;沒點名時模型沒載入 skill,卻用 Bash 掃 .claude/ 讀到清單照樣推薦。
  • 清單本身的時效還行:20 個套件裡多數最近半年內有發版,但 cva 這個 npm 名稱是佔位套件,Liveline 還在 0.0.x,drawer 這類需求清單沒有列。
  1. pick-ui-library 是什麼、解決什麼問題?
  2. 清單推薦哪些函式庫?
  3. 清單過時了嗎?對照 npm 現況
  4. disable-model-invocation 是什麼意思?
  5. 怎麼安裝到 Claude Code?
  6. 實測:6 個情境的結果
  7. 實測抓到的 2 個坑
  8. 其他限制
  9. 適合誰、不適合誰
  10. 延伸資源

🧭 pick-ui-library 是什麼、解決什麼問題?

pick-ui-library 是一份給 AI coding agent 讀的 SKILL.md,全文 85 行,作者是 Emil Kowalski(toast 元件 Sonner 和 drawer 元件 vaul 的作者)。它的工作很單純:你說要做什麼,它從作者挑好的清單裡回你一個函式庫。

repo README 對它的描述是讓 agent 挑對函式庫,「instead of letting AI hand-roll a toast component or install an abandoned package」——不要讓 AI 手刻 toast,也不要裝一個沒人維護的套件。

它規定的流程有四步,原文在 How to use this 那一節:

  1. 辨識任務,不是辨識使用者講的函式庫名。「我要一個下拉選單」是 UI primitives 任務,答案是 base-ui。
  2. 先看 package.json。已經裝了清單裡的函式庫就用它;裝的是競品(例如用 react-window 而不是 Virtuoso),可以提出建議,但沒被要求就不要換依賴。
  3. 只推一個,用一句話說它是做什麼的。清單有明確答案時不要列選單。
  4. 任務不在清單內要明講,再用模型自己的知識推薦,並說清楚已經離開清單。
另外有一條固定開場:只打 /pick-ui-library、沒帶問題時,只能回「I'm ready to pick the right library for your task, my picks come from Emil Kowalski's curated list.」,其他什麼都不說。 GitHub 上 pick-ui-library 的 SKILL.md,frontmatter 顯示 disable-model-invocation 為 true,檔案 85 行

repo 歷史裡,這支 skill 在 2026-07-21 以 commit 049c92e 加入,同一天另一個 commit 修正了 dialkit、torph、Liveline 三條連結,之後只有全 repo 共用的修改。

📋 清單推薦哪些函式庫?

清單分五組,共 19 種任務、20 個函式庫(Leva 那列附了一個替代品 dialkit)。我把它整理成「遇到什麼需求 → 用什麼」:

分組需求推薦
UI 元件無樣式、可及性完整的 dialog、popover、menu、selectbase-ui
UI 元件⌘K 指令面板cmdk
UI 元件toast 通知Sonner
UI 元件一次性密碼/驗證碼輸入框input-otp
UI 元件可調參數的控制面板Leva(替代:dialkit)
動態與視覺通用動畫:spring、layout、進出場motion(Framer Motion)
動態與視覺數字動畫:計數器、價格NumberFlow
動態與視覺文字動畫元件torph
動態與視覺3D 地球Cobe
動態與視覺動態 OG 圖(HTML/CSS 轉 SVG/PNG)Satori
動態與視覺語法高亮shiki
圖表即時串流圖表Liveline
圖表一般圖表與儀表板recharts
互動與效能拖放dnd kit
互動與效能長列表、大表格虛擬化Virtuoso
狀態與樣式狀態管理zustand
狀態與樣式條件組 classNameclsx
狀態與樣式Tailwind 的型別安全變體樣式cva
狀態與樣式主題切換、暗色模式(載入不閃)next-themes
清單裡有三個「怎麼分」的判斷,比表格本身更有用:
  • motion 什麼時候才用:要 spring、layout 動畫、退場動畫或手勢驅動的值才用。單純 hover 或淡入淡出,原文說 CSS transition 就是對的工具。
  • Liveline 和 recharts 怎麼分:資料是即時進來、圖會隨時間捲動的用 Liveline,其他全部 recharts。
  • clsx 和 cva 怎麼分:臨時的條件 class 用 clsx;元件有真正的變體(尺寸、意圖、狀態)值得一個有型別的 API 時用 cva。
最後一節「Common mismatches to catch」列了 6 種要糾正的寫法:手刻 toast、用 <div> 自己做下拉選單和焦點管理、靠重新 render 文字做數字動畫、直接 render 上千列、用一堆 useState 層層傳 props 共享狀態、三層深的 className 三元運算式。

📅 清單過時了嗎?對照 npm 現況

清單只放了官網連結,沒寫版本。我在 2026-10-21 用 npm registry API 抓了每個套件的最新版與 2026-10-12~10-18 這一週的下載量:

套件(npm 名稱)最新版發布日週下載量
@base-ui/react1.9.02026-10-0910,846,815
cmdk1.1.12025-03-1425,375,948
sonner2.0.82026-08-0930,030,645
input-otp1.5.02026-08-1817,414,835
leva0.10.12025-10-31841,639
dialkit2.0.22026-09-09117,652
motion14.5.02026-10-2115,750,774
@number-flow/react0.6.22026-07-181,211,474
torph0.1.32026-09-07105,811
cobe2.0.12026-03-19344,071
satori0.63.22026-10-202,842,555
shiki4.5.02026-10-0116,095,079
liveline0.0.72026-03-12179,434
recharts3.10.12026-07-2533,269,434
@dnd-kit/core6.3.12024-12-0517,050,828
@dnd-kit/react0.5.12026-10-151,053,647
react-virtuoso4.18.192026-10-131,828,413
zustand5.0.152026-08-1337,735,389
clsx2.1.12024-04-2375,784,845
class-variance-authority0.7.12024-11-2640,481,384
next-themes0.4.62025-03-1116,568,729
我的讀法:
  • 沒有一個是棄坑的套件。20 個裡多數在最近半年內有發版,clsx、class-variance-authority、@dnd-kit/core 很久沒發版,但週下載量都在千萬級,屬於功能定型。
  • 成熟度落差很大。Liveline 是 0.0.7、torph 是 0.1.3、dialkit 週下載量 11.7 萬,跟 recharts 的 3,300 萬不是同一個量級。清單是作者的品味選擇,不是市佔排行,用在正式專案前要自己評估。
  • dnd kit 有兩條線。官網 dndkit.com 對應的套件有舊的 @dnd-kit/core(6.3.1)和新的 @dnd-kit/react(0.5.1,上週剛發版),清單沒說要用哪一個。
  • base-ui 已經涵蓋了清單其他列的需求。我查了 @base-ui/react 的版本紀錄:toast 和 combobox 在 1.0.0-rc.1(2025-12-11)出現,drawer 在 1.2.0(2026-02-12),OTP 欄位在 1.4.0(2026-04-13)。也就是 skill 加入時,base-ui 本身已經有 toast 和 OTP,清單仍把這兩項分給 Sonner 和 input-otp。照清單選不會錯,只是同一個專案可能同時裝兩套做同一件事。

🔒 disable-model-invocation 是什麼意思?

pick-ui-library 的 frontmatter 有一行 disable-model-invocation: true,description 最後也寫明「Only runs when explicitly invoked; it does not trigger on its own.」

Claude Code 官方文件(code.claude.com/docs/en/skills)對這個欄位的說明是:設成 true 之後,Claude 不能自己載入這支 skill,它的 description 不會放進 context,只有使用者打 /名稱 時才會把全文載入;它也不會被預先載入到 subagent。跟它相反的是 user-invocable: false,那是只讓 Claude 呼叫、使用者不能用 / 叫用。

所以這支 skill 的用法是:要它出手,就在需求前面打 /pick-ui-library。同 repo 另外兩支 prototype 和 review-animations 也是同樣設定。

⚙️ 怎麼安裝到 Claude Code?

repo README 給的是整包安裝。只要這一支,加上 --skill:

npx skills@latest add emilkowalski/skills --skill pick-ui-library

我在 2026-10-21 用 skills CLI 1.7.4 實際裝過一次,用的是非互動參數:

npx -y skills@1.7.4 add emilkowalski/skills --skill pick-ui-library --agent claude-code --copy -y

結果:

  • 在專案下產生 .claude/skills/pick-ui-library/SKILL.md,內容和 repo commit 2d22863 的版本逐字相同。
  • 另外產生一個 skills-lock.json,記錄來源和雜湊值。
  • 安裝畫面附了三家的安全評估:Gen 標 Safe、Socket 0 alerts、Snyk 標 Low Risk。
之後在 Claude Code 裡打 /pick-ui-library 加上你的需求就能用。

🧪 實測:6 個情境的結果

測試環境:

  • Claude Code 2.1.306,用 claude -p 非互動模式跑,模型是 claude-fable-5-1。
  • 專案是一份最小的 package.json:React 19.2、Tailwind 3.4、Vite 7、TypeScript 5.9,src/ 是空的。s3、s4 另外加了 react-hot-toast。
  • skill 放在專案的 .claude/skills/pick-ui-library/。
  • 我用 --setting-sources project,local 排除自己裝的使用者層級 skill,但我的使用者層級 CLAUDE.md 仍會載入,所以有兩個回覆提到我個人規則裡的東西,跟 skill 無關。
  • 每個 prompt 都附上「先給建議就好,不要安裝或改檔案」。
6 個情境的對照表:輸入、package.json 狀態、推薦結果、耗時與觀察

逐項看:

情境輸入結果
s1/pick-ui-library + 可搜尋、可鍵盤操作的下拉選單推薦 base-ui 的 Combobox,順便排除 cmdk(那是 ⌘K 面板,語意不對)和手刻。安裝指令寫成 npm install @base-ui-components/react
s2/pick-ui-library + 手機底部滑出、可往下拖關閉的 drawer先上網查官方文件,推薦 Base UI 的 Drawer(@base-ui/react 1.9.0),理由是清單外的 vaul 最新版停在 2024 年的 1.1.2
s3/pick-ui-library + toast,專案已裝 react-hot-toast建議沿用 react-hot-toast,說明清單首選是 Sonner,但規則是已有同類套件就不換;最後補一段「什麼時候才值得換 Sonner」
s4同 s3 的需求,不打指令同樣建議沿用 react-hot-toast,沒呼叫 Skill 工具
s5只打 /pick-ui-library2.4 秒、1 個 turn,只回那句固定開場白,一個字都沒多
s6同 s1 的需求,不打指令沒呼叫 Skill 工具,但推薦一樣是 Base UI Combobox,套件名給的是正確的 @base-ui/react
s3 是我認為這支 skill 最有價值的一次:「看 package.json、已有競品就不動」這條規則被照做了,而且它把換套件的條件講清楚,沒有為了推自己清單上的 Sonner 而叫我改依賴。

s5 證明 slash command 有正確展開:如果 skill 沒被載入,模型不會知道那句固定開場白。

🕳️ 實測抓到的 2 個坑

坑一:清單沒寫 npm 套件名,模型會憑記憶補

清單的寫法是「任務 → 函式庫名稱加官網連結」,沒有 npm 套件名。s1 的回覆因此用了模型記憶裡的舊名 @base-ui-components/react。我查 npm registry,這個名稱最新版停在 1.0.0-rc.0,標記為 deprecated,訊息是「Package was renamed to @base-ui/react」。

同樣的需求,s6 的模型有上 npm 查,就給出正確的 @base-ui/react,還提醒舊名已棄用。差別在模型有沒有自己去查,不在 skill。

清單裡會遇到同樣問題的還有 cva:連結是 cva.style,但實際要裝的套件是 class-variance-authority。直接打 npm install cva 裝到的是 latest 標籤指向的 0.0.0,套件描述是「Awesome node module」,同作者的 cva 1.0 目前還在 beta 標籤。

我的做法:用這支 skill 拿到推薦之後,安裝前看一眼 npm 上的套件名稱和最新版,或直接在需求裡加一句「給 npm 套件名並確認未棄用」。

坑二:沒點名不會載入 skill,但檔案還是讀得到

s4 和 s6 都沒打指令,模型也確實沒有透過 Skill 工具載入它。但兩次模型都用 Bash 列出專案檔案,順手把 .claude/skills/pick-ui-library/SKILL.md 的內容讀出來:

  • s4 的回覆寫明「該 skill 設定為只在明確呼叫時才啟用,這次沒呼叫,所以我沒套用它」,然後引用 skill 的規則 2 支持「不換依賴」的結論。
  • s6 則是直接說「專案自己的選庫清單指向它」,照清單推薦 base-ui。
disable-model-invocation 管的是「Claude 能不能透過 Skill 機制自己載入」,它不會把檔案藏起來。skill 放在專案目錄裡,模型探索專案時就可能讀到。如果你想讓這份清單只在點名時影響建議,可以考慮把 skill 裝在使用者層級(~/.claude/skills/),不放進專案的 .claude/,這個做法我沒有實測;反過來,如果你希望團隊不打指令也大致照這份清單走,放在專案裡的效果我只觀察到這兩次,不能當成穩定行為。

🚧 其他限制

  • 清單沒涵蓋的需求,模型會往清單裡擠。drawer 不在 19 種任務裡,skill 的第 4 條規則要模型明講「已離開清單」。s2 的模型沒這樣說,而是把 Drawer 歸到 base-ui 那一列。結論本身合理(base-ui 確實有 Drawer),但讀的人會以為那是清單上的推薦。
  • 清單以 React 生態為主。base-ui、Sonner、cmdk、input-otp、Virtuoso 都是 React 元件,Vue、Svelte 或原生 iOS 大多用不上(shiki、Satori、clsx 不綁框架);同 repo 寫原生的話可以看 write-swift 和 mobile-native。
  • 它只負責選,不負責寫好。toast 選了 Sonner 之後,動畫、手勢、樣式寫得好不好是另一回事。同 repo 的 ask-sonner 是專門處理 Sonner 用法的 skill。
  • Windows 的 Git Bash 用 claude -p 跑會失效。我第一輪在 Git Bash 執行 claude -p "/pick-ui-library ...",MSYS 把開頭的 /pick-ui-library 當成路徑,改寫成 C:/Program Files/Git/pick-ui-library,指令完全沒展開。加上 export MSYS_NO_PATHCONV=1 之後才正常。在 Claude Code 互動畫面裡直接打指令不受影響。

👥 適合誰、不適合誰

適合:

  • 用 React 寫前端、常讓 Claude Code 決定「這個功能要裝什麼套件」的人。打一次指令換來一個有理由的單一答案,比讓模型列三個選項省事。
  • 想讓 AI 先看 package.json 再推薦的人。s3 那種「已有就不換」的判斷,是這份 skill 明文寫下的規則。
不適合:
  • 需要多方比較的選型。skill 第 3 條規定只推一個,你要的是比較表,就直接問模型、不要點名它。
  • 非 React 專案,或公司已經有自己的元件庫與套件白名單。這時候清單和你的規範會互相打架。
  • 希望 AI 不打指令也自動照清單選的人。這支 skill 刻意關掉了自動觸發,想要那種行為要另外寫一支沒設 disable-model-invocation 的 skill,或把清單放進專案的 CLAUDE.md。

🔗 延伸資源

下一步建議:在你手上的 React 專案打一次 /pick-ui-library,丟一個你最近剛好要做的需求(下拉選單、通知、長列表都行),看它有沒有先讀 package.json,再到 npm 上核對它給的套件名稱和最新版。
author
陳
陳彥彤

AI 工程師 · AI 顧問。Java 後端 8 年、AI 工程師 2 年。AI 內訓 · AI 導入顧問 · 前後端與雲端培訓。

support

覺得文章有用可以到 GitHub 給個 star,或是透過信箱聊聊 AI 內訓、AI 導入顧問或前後端 / 雲端培訓。