13 skills · 109 min
Skills
Skill 10 of 13
Pick the right library for a given frontend task from a curated, opinionated list — numbers, OTP inputs, charts, command menus, virtualization, drag and drop, toasts, state…
2 minutes · 522 words · 10 sections
Install
npx skills add emilkowalski/skills --skill pick-ui-librarynpx skills add emilkowalski/skillsThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
When this skill is first invoked without a specific question, respond only with:
I’m ready to pick the right library for your task, my picks come from Emil Kowalski’s curated list.
Do not provide any other information until the user asks a question.
A lookup skill. When invoked with a task (“I need toasts”, “what should I use for drag and drop?”), match the task to the curated list below and recommend the library. These are deliberate, taste-driven picks — don’t substitute alternatives outside this list unless the user asks for one or the task genuinely isn’t covered.
package.json first. If the project already uses a listed library, use it. If it uses a competitor (e.g. react-window instead of Virtuoso), flag the recommendation but don’t churn the dependency without being asked.| Task | Library |
|---|---|
| Unstyled, accessible UI components (dialogs, popovers, menus, selects…) | base-ui (opens in a new tab) |
| Command menus (⌘K palettes) | cmdk (opens in a new tab) |
| Toasts / notifications | Sonner (opens in a new tab) |
| One-time password / verification code inputs | input-otp (opens in a new tab) |
| Customizable GUIs / control panels | Leva — is an alternative |
| Task | Library |
|---|---|
| General-purpose animation (springs, layout animations, enter/exit) | motion (opens in a new tab) (Framer Motion) |
| Animating numbers (counters, prices, stats) | NumberFlow (opens in a new tab) |
| Animated text components | torph (opens in a new tab) |
| 3D globes | Cobe (opens in a new tab) |
| Dynamic OG images (HTML/CSS → SVG/PNG) | Satori |
Reach for motion when you need springs, layout animations, exit animations, or gesture-driven values. A simple hover or fade doesn’t need it — plain CSS transitions are the right tool there.
| Task | Library |
|---|---|
| Real-time / streaming charts | Liveline (opens in a new tab) |
| General charts (static or interactive dashboards) | recharts (opens in a new tab) |
The split: if data points arrive live and the chart scrolls with time, use Liveline. Everything else is recharts.
| Task | Library |
|---|---|
| Drag and drop | dnd kit (opens in a new tab) |
| Virtualization (long lists, large tables) | Virtuoso (opens in a new tab) |
| Task | Library |
|---|---|
| State management | zustand (opens in a new tab) |
Constructing className strings conditionally | clsx (opens in a new tab) |
| Type-safe, variant-driven styling for Tailwind | cva (opens in a new tab) |
| Theme switching / dark mode (no flash on load) | next-themes (opens in a new tab) |
The styling split: clsx for ad-hoc conditional classes; cva when a component has real variants (size, intent, state) that deserve a typed API. They compose — cva uses clsx-style inputs internally.
<div>-based dropdown/dialog with manual focus handling → base-ui, which handles accessibility, focus trapping, and dismissal.useState-per-component web of props for shared state → zustand.Pick the right library for a given frontend task from a curated, opinionated list — numbers, OTP inputs, charts, command menus, virtualization, drag and drop, toasts, state, styling, and more. Only runs when explicitly invoked; it does not trigger on its own.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
main, last pushed 23 September 2026.SKILL.md, not by matching a directory convention. One layout observed: skills/*/SKILL.md.h1 and no skipped levels:/emilkowalski/skills.md, and each skill at its own .md URL.| Syntax highlighting | shiki (opens in a new tab) |