the duck ui component library

59+ production-ready components with a copy-source philosophy. Own your code, not your dependencies.

59+ Components, Zero Lock-In

Duck UI is a component library built on top of the GentleDuck ecosystem. It ships over 59 production-ready components covering forms, navigation, data display, overlays, and layout.

But unlike most component libraries, duck-ui does not install as a dependency. Instead, the CLI copies source code directly into your project. You own every line. You can read it, modify it, delete parts you do not need, and never worry about a breaking upstream update.

Loading diagram...


The Component Catalog

Form Components

ComponentDescription
ButtonCustomizable action trigger with 6 variants and 5 sizes
Button GroupGrouped buttons with shared separators
InputText input with label, description, and error states
Input GroupCompound input with prefix/suffix addons
Input OTPOne-time password input with configurable length
TextareaMulti-line text input
CheckboxBinary toggle with indeterminate state
Radio GroupSingle-selection from a set
SelectDropdown selection with search and groups
ComboboxSearchable select with keyboard navigation
SwitchToggle switch with motion
SliderRange input with min/max/step
CalendarDate picker grid
Date PickerCalendar with popover
LabelAccessible form label
FieldForm field wrapper with label + description + error
React Hook FormPre-wired form primitives for react-hook-form
JSON EditorStructured JSON editing with validation
ComponentDescription
CommandCommand palette with fuzzy search
Navigation MenuMulti-level navigation with flyout panels
BreadcrumbPath navigation with separator customization
MenubarApplication menu bar
TabsTabbed content navigation
PaginationPage navigation controls

Data Display

ComponentDescription
TableData table with sorting, filtering, and selection
Data TableFull-featured data grid with column controls
CardContent container with header, body, and footer
BadgeStatus labels and counters
AvatarUser avatars with fallback initials
KbdKeyboard shortcut display
TypographyHeading and prose components
SkeletonLoading placeholder
EmptyEmpty state illustration
ChartData visualization (Recharts v3)

Overlays

ComponentDescription
DialogModal dialog with focus trapping
Alert DialogConfirmation dialog with required action
SheetSlide-in panel from any edge
DrawerBottom sheet with drag-to-dismiss
Dropdown MenuContext-aware dropdown with keyboard navigation
Context MenuRight-click context menu
PopoverPositioned floating panel
TooltipHover/focus information overlay
Hover CardRich content on hover

Layout

ComponentDescription
AccordionCollapsible content sections
CollapsibleSingle collapsible region
Aspect RatioFixed aspect ratio container
ResizableResizable panels with drag handles
Scroll AreaCustom scrollbar with cross-browser styling
SeparatorVisual divider
CarouselSwipeable content carousel
Preview PanelContent preview with multiple layout modes

Feedback

ComponentDescription
AlertStatus messages with icon and description
SonnerToast notifications
ProgressProgress bar with animation
TogglePressed/unpressed state button
Toggle GroupMulti-toggle selection

The CLI Workflow

Adding components is one command:

# Initialize a new project with components
bunx @gentleduck/cli init button dialog input select
 
# Add more components later
bunx @gentleduck/cli add command combobox data-table
# Initialize a new project with components
bunx @gentleduck/cli init button dialog input select
 
# Add more components later
bunx @gentleduck/cli add command combobox data-table

The CLI:

  1. Resolves dependencies between components (e.g., combobox needs popover + command)
  2. Copies source files into your project
  3. Installs npm dependencies (@gentleduck/primitives, @gentleduck/variants, etc.)
  4. Configures Tailwind CSS if needed

Why Copy Source?

Most component libraries are black boxes. You install a package, use the API, and hope the defaults work for your design. When they do not, you fight the abstraction with CSS overrides, wrapper components, or abandoned forks.

Duck UI takes a different approach:

  • Full control -- Every component is a file you own. Change the border radius, swap an icon, add a prop, remove a feature.
  • No version lock -- You are not coupled to upstream releases. Your code, your pace.
  • Learn by reading -- The source is right there in your project. See exactly how a dialog manages focus or how a combobox handles keyboard events.
  • Tree-shaking by default -- You only have the components you use. No unused code in your bundle.

Built on the Ecosystem

Every component is built using the same GentleDuck packages you can adopt independently:

  • @gentleduck/primitives -- Headless behavior (focus, keyboard, ARIA)
  • @gentleduck/variants -- Type-safe styling with cva()
  • @gentleduck/hooks -- React hooks for component logic
  • @gentleduck/motion -- Enter/exit animations
  • @gentleduck/libs -- Utilities (cn, Slot, Portal)

The components are the reference implementation of these packages working together. Reading the source teaches you how to build your own components using the same patterns.


Getting Started