Accessible parts, no styles attached
Headless React primitives with roles, focus, and keyboard handled for you. Shared internals keep Alert Dialog at 1.6 KB and Popover at 2.4 KB.
Shared internals
Slot, Presence, Popper, and focus scope load once for every primitive. Alert Dialog is 1.6 KB and Popover is 2.4 KB.
Accessible by default
Every primitive ships with the right roles, states, and keyboard behavior. Compose them and ARIA is already wired.
Compound parts
Compose
Root,Trigger,Content, andPortalwith scoped context. Each part owns one job, with no prop drilling.Keyboard support
Roving focus, type-ahead, arrow keys, and focus trapping, with the same behavior across menus, dialogs, and selects.
Familiar API
Compound parts,
asChild, anddata-stateattributes. If you’ve used a headless library before, you know the vocabulary.40+ primitives
Dialog, Popover, Select, Menu, Command, Calendar, Input OTP, Navigation Menu, and more. All headless and unstyled.
Install
Import each primitive from its own subpath.
Install
bun add @gentleduck/primitivesImport a primitive
import { Root, Trigger, Portal, Content } from '@gentleduck/primitives/dialog'
Free & open source
gentleduck is MIT licensed and will always be free and open source. Every package ships with full source access — fork it, modify it, own it.