Skip to content

Ark v6 #3616

@cschroeter

Description

@cschroeter

Status: Draft
Target Release: Q2 2026 (April - Juli)
Last Updated: April 02, 2026

Overview

Ark UI v6 is all about making your life easier as a developer. We're introducing changes that give you more flexibility and consistency when building user interfaces. Here's what's coming.

Composition — asChildrender Prop

The biggest change in v6 is how you compose custom elements with Ark UI components. The asChild prop is being replaced by a render prop, giving you explicit control over what gets rendered.

Currently, asChild merges props into a single child element:

<Popover.Trigger asChild>
  <Button>Open Popover</Button>
</Popover.Trigger>

In v6, you'll use the render prop instead:

<Popover.Trigger render={<Button>Open Popover</Button>} />

The render prop also accepts a function for full control over the rendered output:

<Popover.Trigger
  render={(props) => <Button {...props}>Open Popover</Button>}
/>

This approach is more explicit, avoids the single-child limitation of asChild, and works consistently across all components - including Indicator components where it unlocks state-based rendering (see below).

Indicator

Next up, we're redesigning our Indicator components to match specific states and allow you to set fallbacks. At the moment, they look something like this:

<Menu.ItemIndicator>
    <CheckIcon />
</Menu.ItemIndicator>
<Clipboard.Indicator copied={<CheckIcon />}>
    <ClipboardCopyIcon />
</Clipboard.Indicator>
<Checkbox.Indicator>
    <CheckIcon />
</Checkbox.Indicator>
<Checkbox.Indicator indeterminate>
    <MinusIcon />
</Checkbox.Indicator>

Take a look at Menu.ItemIndicator, for example. How do you know it's meant for the selected state of an item? You don't. Additionally, if the item isn't selected, nothing is rendered, making it difficult for flexbox or grid layouts to work properly.

Altogether, these components not only lack consistency but also flexibility. In the next major version, the Indicator component will expose a render prop that gives you full control over what's rendered based on the component's state:

<Checkbox.Indicator
  render={(props, state) => {
    if (state.status === 'checked') {
      return <CheckIcon {...props} />
    } else if (state.status === 'indeterminate') {
      return <MinusIcon {...props} />
    } else {
      return <SquareIcon {...props} />
    }
  }}
/>

Simplified Data Attributes

We're making the DOM output cleaner and more semantic. Instead of generic data attributes with scope and part information, v6 introduces component-specific data attributes that are easier to understand and work with.

Currently, components generate verbose data attributes that include scope and part information:

<Popover.Trigger>Show Popover</Popover.Trigger>

renders

<button id="popover:123:trigger" data-scope="popover" data-part="trigger">Show Popover</button>

In v6, we're simplifying this to use concise, component-specific data attributes:

<Popover.Trigger>Show Popover</Popover.Trigger>

renders

<button id="popover:123:trigger" data-popover-trigger="123">Show Popover</button>

This change is helpful when composing components with the render prop as there will no longer be a potential clash of data-part or data-scope attributes.

Anatomy

import { dialogAnatomy } from '@ark-ui/[framework]' // moved 
import { dialogAnatomy } from '@ark-ui/[framework]/dialog'
import { dialogAnatomy } from '@ark-ui/[framework]/anatomy' // new
import { dialogAnatomy } from '@ark-ui/[framework]/dialog'

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions