Migration - Radix Vue to Akar
This guide provides step-by-step instructions for developers transitioning their projects from Radix Vue to Akar.
Akar v2.0.20 already includes these Reka v2 API changes. If you are coming from
radix-vue or reka-ui, switch the package name to akar and apply the breakages below that you have not already adopted.Installation
First, install the latest akar.
pnpm add akar
yarn add akar
npm install akar
bun add akar
Congratulations! 🎉 Now that you've installed the above package, let's perform the migration! The first 2 steps are relatively simple. Just do a global search and replace for the following changes.
Import Statement Changes
The primary change in imports is replacing radix-vue or reka-ui with akar.
<script setup lang="ts">
import { TooltipPortal, TooltipRoot, TooltipTrigger } from 'akar';import { TooltipPortal, TooltipRoot, TooltipTrigger } from 'radix-vue';</script>
Naming Convention Changes
CSS variable and data attributes names have been updated to use the reka prefix instead of radix.
--radix-accordion-content-width: 300px; --akar-accordion-content-width: 300px;
[data-radix-collection-item] {
}[data-reka-collection-item] {
}Component Breaking Changes
Combobox
- Remove
filter-functionprops -Comboboxhas been refactored and improved to support better custom filtering. Read more.<template> <ComboboxRoot :filter-function="customFilter" /> </template> - Replace
searchTermprops of Root to Input'sv-model - Move
displayValueprops from Root to Input<template> <ComboboxRoot v-model:search-term="search" :display-value="(v) => v.name" /> <ComboboxRoot> <ComboboxInput v-model="search" :display-value="(v) => v.name" /> </ComboboxRoot> </template>
Arrow
- Improve arrow polygon - Change the svg polygon to allow better styling.
Form component
- Rename controlled state to
v-model- Replacev-model:checked,v-model:pressedwith more familiar API for form component.
<template>
<CheckboxRoot v-model:checked="value" />
<CheckboxRoot v-model="value" />
</template>
- Reposition
VisuallyHidden- Previously,VisuallyHiddenwere positioned at the root node, causing style scoped to not be applied.
Menu CheckboxItem
- Similar to the changes in form component, the API for binding
CheckboxItemhas been changed fromv-model:checkedtov-model.
<template>
<DropdownMenuCheckboxItem v-model:checked="value" />
<DropdownMenuCheckboxItem v-model="value" />
<DropdownMenuCheckboxItem checked />
<DropdownMenuCheckboxItem :model-value="true" />
</template>
Pagination
- Required
itemsPerPageprop - TheitemsPerPageprop is now required instead of relying on a default value.<template> <PaginationRoot :items-per-page="10" /> </template>
Calendar
- Remove deprecated step prop - Use
prevPage/nextPageprops for greater control.<script setup lang="ts"> function pagingFunc(date: DateValue, sign: -1 | 1) { if (sign === -1) { return date.subtract({ years: 1 }); } return date.add({ years: 1 });}</script> <template> <CalendarPrev step="year" /> <CalendarPrev :prev-page="(date: DateValue) => pagingFunc(date, -1)" /> <CalendarNext step="year" /> <CalendarNext :next-page="(date: DateValue) => pagingFunc(date, 1)" /> </template>
Select
SelectValueno longer renders a teleported element - The previous implementation ofSelectValuerendered the selectedSelectItemthrough a teleported fragment. This caused SSR flicker and unnecessary computation.<template> <SelectValue> <!-- render the content similar to `SelectItem` --> </SelectValue> </template>
Presence
To have better support for SSR content, we also modified the logic around the usage of forceMount for components that utilize Presence:
AccordionCollapsibleTabsNavigationMenu
forceMount will now render the component even though the state is inactive. You are now required to handle the visibility logic of the component manually.
<template>
<TabsRoot
v-slot="{ modelValue }"
default-value="tab1"
>
<TabsContent
value="tab1"
force-mount
:hidden="modelValue !== 'tab1'"
>
…
</TabsContent>
<TabsContent
value="tab2"
force-mount
:hidden="modelValue !== 'tab2'"
>
…
</TabsContent>
</TabsRoot>
</template>
For Nuxt module users
If you are using Nuxt, you need to update your module import.
// nuxt.config.ts
export default defineNuxtConfig({
modules: [
"radix-vue/nuxt", "akar/nuxt", ],
});