AI-native · Unstyled · Compound components


Headless, compound components with AI-integrated docs. Zero CSS shipped — style everything through data-* attributes that reflect interactive state.


💬1
Prompt
Describe what you want to build
📡2
AI reads docs
llms.txt, MCP, and SKILL.md give AI full context
⌨️3
Generate
AI writes component code with correct API usage
🎨4
Customize
Style with data-* attributes — you own every pixel
🚀5
Ship
Production-ready in minutes, not hours

AI-native ecosystem

Built for the AI era.
Not retrofitted.

Wire UI was designed from day one to be consumed by both humans and machines. Every component, every API surface, every doc page — structured for AI to read, understand, and generate production code from.

MCP Server
First-class Model Context Protocol server for Claude, Cursor, and other AI assistants. Structured access to Wire UI's full API — accurate, versioned, and complete. No hallucinations, no outdated docs.
AI-friendly exports
llms.txt, llms-full.txt, and SKILL.md — structured exports purpose-built for LLM consumption. Your AI tools get first-class data, not scraped HTML.
Teach AI your conventions
SKILL.md lets you define your project's patterns and preferences. Generated code matches your team's style from the first prompt.
@wire-ui/mcp

Developer experience
to love

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

🤖
AI-native
AI-integrated docs with llms.txt, machine-readable API references, and MCP server support. Built for AI-assisted workflows.
🎨
Unstyled primitives
Zero CSS shipped. No design opinions. Every component is a bare building block — you own every pixel.
🧩
Compound components
Complex widgets follow the Component.Part pattern so you control markup order and nesting.
📡
State via data-* attributes
Every interactive state — hover, focus, active, disabled, open — exposed as a data attribute. Style with plain CSS.
🔁
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.
Dropdown.tsx
import { Dropdown } from '@wire-ui/react'

export const UserMenu = () => {
  const handleSelect = (action: string) => {
    console.log('selected:', action)
  }

  return (
    <Dropdown.Root>
      <Dropdown.Trigger>Open Menu</Dropdown.Trigger>
      <Dropdown.Menu>
        <div onClick={() => handleSelect('profile')}>Profile</div>
        <div onClick={() => handleSelect('settings')}>Settings</div>
        <div onClick={() => handleSelect('signout')}>Sign out</div>
      </Dropdown.Menu>
    </Dropdown.Root>
  )
}

Every feature, side by side

Honest comparison against the major headless component libraries. Where we win, where we tie, and where the field beats us.

FeatureWire UIRadix UIHeadless UIReact AriaArk UIBase UI
Unstyled (zero CSS)
Multi-frameworkReact + Vue
TypeScript native
asChild / polymorphismv2+
data-* state attributes
WCAG AA / ARIA
llms.txt
MCP server
SKILL.md
LicenseMITMITMITApache 2.0MITMIT

Data captured 2026-04-22. Numbers approximate. Captured from public docs and repos. Submit a correction →


👋

An active and friendly community

Join our fast-growing community