Skip to main content
@gentleduck/primitives

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, and Portal with 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, and data-state attributes. 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.

  1. Install

    bun add @gentleduck/primitives
  2. Import 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.

Become a Sponsor