โšกReact 19 ยท Headless ยท Zero CSS

Core building blocks
for your design system

Unstyled, accessible React 19 primitives. Style everything with your own CSS using data-* attributes that reflect interactive state.

App.tsx
import { Button } from '@wire-ui/react'

export default function App() {
  return (
    <Button
      className="
        px-4 py-2 rounded-lg bg-indigo-600 text-white font-medium
        [data-hover]:bg-indigo-700
        [data-active]:scale-95
        [data-focus-visible]:ring-2 [data-focus-visible]:ring-indigo-500
        [data-disabled]:opacity-40 [data-disabled]:cursor-not-allowed
      "
    >
      Save changes
    </Button>
  )
}

The person behind wire-ui

Designed and built by a senior frontend engineer who got tired of fighting component library styles.

Jerald Austero
Jerald Austero
Sr. Frontend Engineer
@jaoaustero
ReactVueTypeScriptHeadless UI

Developer experience
to love

Develop with an open, thought-out API that stays out of your way.

๐ŸŽจ
Unstyled by default
Zero CSS shipped. No design opinions baked in. You own every pixel of your design system.
๐Ÿ“ก
State via data-* attributes
Every interactive state โ€” hover, focus, active, disabled, open โ€” exposed as a data attribute. Style with plain CSS.
๐Ÿงฉ
Compound components
Complex widgets follow the Component.Part pattern so you control markup order and nesting.
๐Ÿ”ท
TypeScript first
Full type safety across every component and prop. Autocomplete, narrowing, and no any escapes.
๐Ÿ”
asChild polymorphism
Merge all behaviour onto your own element โ€” perfect for router links, icon buttons, and custom wrappers.
โœ…
Consumer-owned validation
Form components expose invalidType and errorMessage but never validate internally. Your logic, your rules.
Modal.tsx
import { Modal } from '@wire-ui/react'

<Modal>
  {/* Trigger โ€” any element */}
  <Modal.Trigger asChild>
    <button className="btn">Open</button>
  </Modal.Trigger>

  {/* Backdrop */}
  <Modal.Backdrop className="
    fixed inset-0 bg-black/50
    [data-open]:opacity-100
    [data-closed]:opacity-0
  " />

  {/* Panel */}
  <Modal.Panel className="
    fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2
    bg-white rounded-xl shadow-xl p-6 w-full max-w-md
    [data-open]:scale-100
    [data-closed]:scale-95
  ">
    <Modal.Title>Are you sure?</Modal.Title>
    <Modal.Description>This cannot be undone.</Modal.Description>
    <Modal.Close asChild>
      <button className="btn-danger">Confirm</button>
    </Modal.Close>
  </Modal.Panel>
</Modal>

๐Ÿ‘‹

An active and friendly community

Join our fast-growing community

GitHub
wire-ui/wire-ui
โ†’