Headless, accessible UI primitives for Alpine.js, built with https://github.com/eldomagan/alpine-define-component.
This library provides unstyled, behavior-only components inspired by:
The goal is to give you composable Alpine components with correct state management, keyboard interactions, and ARIA attributes, while leaving all styling and markup control to you.
- Headless (no styles, no markup assumptions)
- Accessible by default (keyboard and ARIA patterns applied)
- Per-component imports
- Built on Alpine.js v3
npm install alpine-headless-uiimport Alpine from 'alpinejs'
import AlpineHeadlessUI from 'alpine-headless-ui'
Alpine.plugin(AlpineHeadlessUI)
Alpine.start()This registers all available headless ui components globally.
You can import and register only the components you need.
import Alpine from 'alpinejs'
import dialog from 'alpine-headless-ui/dialog'
import menu from 'alpine-headless-ui/menu'
Alpine.plugin(dialog)
Alpine.plugin(menu)
Alpine.start()This keeps your bundle size minimal.
All components follow the same pattern:
- A root element using
x-<component> - Named parts using
x-<component>:<part> - Optional scoped sub-parts for repeated items
The exact HTML structure is up to you.
<div x-dialog>
<button x-dialog:trigger>Open Dialog</button>
<div x-dialog:backdrop></div>
<div x-dialog:positioner>
<div x-dialog:content>
<h2 x-dialog:title>Dialog Title</h2>
<p x-dialog:description>
This is a basic dialog example. Click outside or press Escape to close.
</p>
<button x-dialog:close-trigger>Close</button>
</div>
</div>
</div>- Focus is trapped inside the dialog when open
- Escape closes the dialog
- Focus returns to the trigger on close
- Backdrop click closes the dialog
- Body scroll prevented when open
Alpine Headless UI components aim to follow WAI-ARIA authoring practices:
- Correct roles (
dialog,menu,combobox, etc.) - Keyboard interactions matching platform expectations
- Focus management on open and close
Behavior patterns are inspired by Zag.js state machines, adapted to Alpine idioms.
You are responsible for:
- Visual focus styles
- Animations and transitions
- Layout and spacing
Inspired by:
- Zag.js - State machine patterns for accessible components
- alpine-zag - Alpine.js integration with Zag.js
Created by:
This project is open-sourced under the MIT license.