Skip to Content
⭐️ Leave a star →
Getting Started

Getting Started

Installation

Install the package

npm install @wire-ui/react

Wire UI has no production dependencies. React is a peer dependency.

Add peer dependencies

If you don’t already have React:

npm install react@^19 react-dom@^19

Use a component

import { Button } from '@wire-ui/react' export function SaveButton() { return ( <Button type="submit" className="px-4 py-2 rounded bg-blue-600 text-white"> Save changes </Button> ) }

Styling approach

Wire UI ships no CSS. All interactive state is exposed through data-* attributes. Target them with any CSS approach you prefer.

<Button className=" px-4 py-2 rounded bg-blue-600 text-white transition-all [data-hover]:bg-blue-700 [data-active]:scale-95 [data-focus-visible]:ring-2 [data-focus-visible]:ring-offset-2 [data-disabled]:opacity-50 [data-disabled]:cursor-not-allowed "> Submit </Button>

Compound components

Complex components use a compound pattern. You compose the markup yourself:

import { Input } from '@wire-ui/react' <Input.Root value={value} onChange={setValue}> <Input.Label>Email address</Input.Label> <Input.Field type="email" placeholder="you@example.com" /> <Input.Error /> </Input.Root>

You control the DOM order. Need the error above the field? Swap them. Need a wrapper div between label and field? Add it. Wire UI never dictates structure.

Validation pattern

Wire UI components do not validate internally. You own validation — set invalidType when your logic determines the field is invalid:

const [email, setEmail] = useState('') const [invalidType, setInvalidType] = useState('') function handleSubmit(e: React.FormEvent) { e.preventDefault() if (!email) setInvalidType('required') else if (!email.includes('@')) setInvalidType('email') else setInvalidType('') // clear the error } <Input.Root value={email} onChange={setEmail} invalidType={invalidType} errorMessage={{ required: 'Email is required', email: 'Enter a valid email address', }} > <Input.Label>Email</Input.Label> <Input.Field type="email" /> <Input.Error /> </Input.Root>

TypeScript

All prop types are exported:

import type { ButtonProps, InputRootProps, TextareaRootProps, PasswordRootProps, ModalRootProps, AccordionRootProps, SearchOption, Size, Status, } from '@wire-ui/react'
Last updated on

MIT License © 2026 wire-ui

Getting Started – Wire UI