Skip to content
UniAria
Color scheme
Contrast
Color scheme
Contrast

Introduction

UniAria is a library of accessible component behavior. It gives a button, a checkbox, a dialog or a combo box everything except its look: keyboard handling, focus management, ARIA roles and states, dismissal, selection, positioning and the small browser fixes that real users need. You bring the markup and the CSS.

Each component’s behavior is written once, in plain TypeScript, as a definition. Three small adapters bind every definition to a framework:

  • @uniaria/react: useBehavior(definition, props) returns props to spread onto your elements.
  • @uniaria/vue: the same composable, with props to bind with v-bind.
  • @uniaria/elements: the components are also light-DOM custom elements, such as <uni-button>, that wrap your markup. They work in plain HTML and in any framework that renders HTML: Svelte, Angular, server templates.

Every adapter runs the same definition, and the same conformance tests check each.

Principles

Behavior once, for every framework. A design system that serves React and something else today maintains two implementations of every widget, and their accessibility drifts apart. With UniAria, a fix lands in one place.

Your markup, your CSS. UniAria adds no elements to your markup, with two exceptions: a live region for announcements, and the options of Select’s hidden native <select>. It writes attributes to the elements you mark as parts: ARIA attributes, the part markers (data-uni on the root, data-element on the other parts), and state attributes such as data-pressed or data-open. Your CSS targets those. See Styling.

No re-renders for internal state. Hovering a button, pressing it, moving the highlight through a long list or opening a popover changes no React or Vue state of yours. UniAria writes the change straight to the DOM. A component renders again only for state it asks for, through a selector. See State.

Native elements first. A real <button>, <input type="checkbox"> or <dialog> sits under each component wherever HTML has one, so forms, autofill, browser extensions and assistive technology get what they expect. Overlays open in the browser’s top layer with the Popover API and <dialog>, so nothing is moved into a portal.

Accessibility that is checked, not claimed. Each component follows its WAI-ARIA Authoring Practices pattern, and React Aria is the reference for browser and screen-reader edge cases. Conformance scenarios drive real mouse, touch and keyboard input in Chromium, Firefox and WebKit, check what a screen reader would say, and run nightly against VoiceOver and NVDA. See Accessibility.

Small and dependency-light. Small utilities are written in-house. The only runtime dependencies are @internationalized/number for NumberField’s locale-aware numbers, and TanStack Virtual, bundled into the optional @uniaria/core/virtual entry.

What UniAria is not

  • Not a styling library. The core and the adapters have no look. The optional @uniaria/styles package adds one, the default styles, written against the same part markers and state attributes your own CSS would use, and nothing else depends on it. UniAria itself sets a style only where a behavior can’t work without it, such as touch-action on pressable elements, and such rules yield to yours.
  • Not a form library. Fields show validation state you give them; they don’t validate. See Forms.
  • Not a set of framework components. In React and Vue you get a hook or a composable that returns props, not <Button> components, so your design system decides the component API.

For how these choices set UniAria apart from React Aria, Radix, Headless UI, Base UI and Zag.js, and when one of them fits better, see Compared with others.

Components

UniAria covers Button (with link mode), ToggleButton, Field, TextField (inputs and text areas), NumberField, Checkbox, CheckboxGroup, Switch, RadioGroup, Dialog, Popover, Tooltip, Listbox, Autocomplete, Select and Combobox. TextInput, the input inside the text fields, has no element and is for your own definitions. See Components and Custom components.

Status

UniAria is a pre-release, at 0.x on npm. It is built by AI agents and reviewed by its author, @tenphi, who also made Tasty and Glaze. Its first consumer is Cube UI Kit. See Contributing for how the work is organized.