- Accordion
- Action Bar
- Alert Dialog
- Alert
- Announcement
- Aspect Ratio
- Autocomplete
- Avatar
- Badge
- Bottom Navigation
- Breadcrumb
- Button Group
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Circular Slider
- Clipboard
- Collapsible
- Color Picker
- Combobox
- Command
- Context Menu
- Data List
- Date Picker
- Dialog
- Drawer
- Editable
- Field
- File Upload
- Float
- Floating Panel
- Frame
- Hint
- Hover Card
- Image Cropper
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Link Overlay
- Listbox
- Marquee
- Menu
- Native Select
- Number Input
- Pagination
- Popover
- Progress
- Prose
- QR Code
- Radio Group
- Rating
- Resizable
- Scroll Area
- Segment Group
- Select
- Separator
- Sheet
- Sidebar
- Signature Pad
- Skeleton
- Skip Nav
- Slider
- Spinner
- Status
- Steps
- Switch
- Table
- Tabs
- Textarea
- Timer
- Toast
- Toggle Group
- Toggle Tooltip
- Toggle
- Tooltip
- Tour
- Tree View
Render a different element as the component while inheriting its styles and behavior.
The asChild prop lets you swap the default element for your own—a link, a custom button, whatever—while keeping the component’s styles, props, and behavior. You get composition without extra wrapper divs or duplicated markup. That’s useful when you need semantic HTML (like an anchor for navigation) but want it to look and act like a Button or Badge.
Creating new Components
When you build custom components with the Ark factory, they automatically support asChild because Ark’s factory handles the prop under the hood. You don’t have to do anything special—just pass through props and the child merges in:
import { ark } from '@ark-ui/react/factory' interface ButtonExampleProps extends React.ComponentProps<typeof ark.button> {} export const ButtonExample = (props: ButtonExampleProps) => ( <ark.button {...props} /> )
import Link from "next/link"; <ButtonExample asChild> <Link href="/login">Login</Link> </ButtonExample>
Examples
Link
Need a login link that looks like a button? Use asChild so the Link becomes the rendered element—no extra div, and it keeps proper semantics for SEO and screen readers.
<Button asChild> <Link href="/login">Login</Link> </Button>
Badge
Sometimes a badge is clickable—a tag that goes somewhere, or a category filter. Wrap a Link with Badge and asChild, and the link gets the badge styling while staying a real anchor.
<Badge asChild> <Link href="/tags/react">React</Link> </Badge>
Dialog
Trigger components like DialogTrigger often need a button. Instead of nesting a button inside a trigger div, pass the Button as the child and let it become the trigger. Same accessibility, less markup.
<Dialog> <DialogTrigger asChild> <Button>Open dialog</Button> </DialogTrigger> {/* ... */} </Dialog>
Menu
Same pattern for menus. The Button merges into MenuTrigger, so you get a single element that opens the menu with the right keyboard and focus behavior.
<Menu> <MenuTrigger asChild> <Button>Open</Button> </MenuTrigger> {/* ... */} </Menu>
Popover
Popovers work the same way. Use asChild on PopoverTrigger and pass your Button—no wrapper needed.
<Popover> <PopoverTrigger asChild> <Button>Open Popover</Button> </PopoverTrigger> {/* ... */} </Popover>
When to use it
Reach for asChild when you want the right element in the DOM: links for navigation, buttons for triggers, or any case where semantic HTML matters. It’s handy for forms (submit links styled as buttons), navigation bars, and anywhere you’d otherwise wrap something in a div just to apply styles.