PluginBench
Skill
Fail
Audit score 45

reka-ui

onmax/nuxt-skills

Unstyled, accessible Vue 3 component primitives with WAI-ARIA compliance and composition patterns.

What is reka-ui?

Reka UI provides headless, WAI-ARIA compliant Vue 3 components for building accessible interfaces from scratch. Use it when you need unstyled primitives, are building on Nuxt UI or shadcn-vue, or require fine-grained control over component behavior and styling.

  • Render unstyled, accessible component primitives (Dialog, Select, Combobox, Menu, Popover, Toast, etc.)
  • Support controlled and uncontrolled state patterns via v-model and default* props
  • Compose components with asChild to merge props and behavior onto custom elements
  • Optimize large lists with virtualization support in Combobox, Listbox, and Tree
  • Provide WAI-ARIA compliant patterns and context injection for nested component access
  • Handle animations with forceMount and portal rendering for overlay components

How to install reka-ui

npx skills add https://github.com/onmax/nuxt-skills --skill reka-ui
Prerequisites
  • Vue 3 project or Nuxt 3 application
  • Install via: npx skills add https://github.com/onmax/nuxt-skills --skill reka-ui
  • For Nuxt: add reka-ui/nuxt module to nuxt.config.ts; for Vite: configure unplugin-vue-components with RekaResolver
Claude Code
Cursor
Windsurf
Cline

How to use reka-ui

  1. 1.Import the component parts you need (e.g., DialogRoot, DialogTrigger, DialogContent)
  2. 2.Wrap your UI in the Root component and bind state with v-model:open or default* props
  3. 3.Compose child parts (Trigger, Portal, Overlay, Content, Close) in the correct order
  4. 4.Use asChild on parts to render as custom elements instead of wrappers
  5. 5.Apply your own CSS classes to style the unstyled components
  6. 6.Consult references/components.md to browse available components by category (Form, Overlay, Menu, Data, etc.)

Use cases

Good for
  • Building a custom design system or component library on top of Reka primitives
  • Implementing accessible form controls (selects, comboboxes, date pickers) in a Nuxt app
  • Creating a headless UI for a styled framework like Nuxt UI or shadcn-vue
  • Rendering large virtualized lists or trees with performance optimization
  • Composing custom trigger buttons or wrappers using asChild composition
Who it's for
  • Vue 3 / Nuxt developers building custom component libraries
  • Teams implementing design systems with accessibility requirements
  • Developers using Nuxt UI, shadcn-vue, or similar Reka-based libraries
  • Frontend engineers needing fine-grained control over component state and styling

reka-ui FAQ

What's the difference between controlled and uncontrolled state?

Controlled state uses v-model:open (or similar) to sync component state with your data; uncontrolled uses default* props and manages state internally. Choose controlled when you need to react to state changes, uncontrolled for simpler use cases.

What does asChild do?

asChild renders the component as a child element instead of a wrapper, merging all props and behavior onto your custom element. Useful for applying Reka UI patterns to your own button or div without extra DOM nodes.

How do I style Reka UI components?

Reka UI is unstyled by default. Add your own CSS classes to component parts, or use a styled library like Nuxt UI or shadcn-vue that wraps Reka UI with pre-built styles.

Does Reka UI support virtualization for large lists?

Yes. Combobox, Listbox, and Tree components support virtualization. Use estimateSize prop (accepts a function in v2.7.0+) to optimize rendering of thousands of items.

Is Reka UI accessible out of the box?

Yes. All components follow WAI-ARIA patterns and include keyboard navigation, focus management, and semantic HTML. No additional setup required for basic accessibility.

Full instructions (SKILL.md)

Source of truth, from onmax/nuxt-skills.


name: reka-ui description: Use when building with Reka UI (headless Vue components) - provides component API, accessibility patterns, composition (asChild), controlled/uncontrolled state, virtualization, and styling integration. Formerly Radix Vue. license: MIT

Reka UI

Unstyled, accessible Vue 3 component primitives. WAI-ARIA compliant. Previously Radix Vue.

Current version: v2.8.0 (January 2026)

When to Use

  • Building headless/unstyled components from scratch
  • Need WAI-ARIA compliant components
  • Using Nuxt UI, shadcn-vue, or other Reka-based libraries
  • Implementing accessible forms, dialogs, menus, popovers

For Vue patterns: use vue skill

Available Guidance

FileTopics
references/components.mdComponent index by category (Form, Date, Overlay, Menu, Data, etc.)
components/*.mdPer-component details (dialog.md, select.md, etc.)

Guides (see reka-ui.com): Styling, Animation, Composition, SSR, Namespaced, Dates, i18n, Controlled State, Inject Context, Virtualization, Migration

Loading Files

Consider loading these reference files based on your task:

DO NOT load all files at once. Load only what's relevant to your current task.

For styled Nuxt components built on Reka UI: use nuxt-ui skill

Key Concepts

ConceptDescription
asChildRender as child element instead of wrapper, merging props/behavior
Controlled/UncontrolledUse v-model for controlled, default* props for uncontrolled
PartsComponents split into Root, Trigger, Content, Portal, etc.
forceMountKeep element in DOM for animation libraries
VirtualizationOptimize large lists (Combobox, Listbox, Tree) with virtual scrolling
Context InjectionAccess component context from child components

Installation

// nuxt.config.ts (auto-imports all components)
export default defineNuxtConfig({
  modules: ['reka-ui/nuxt']
})
import { RekaResolver } from 'reka-ui/resolver'
// vite.config.ts (with auto-import resolver)
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    vue(),
    Components({ resolvers: [RekaResolver()] })
  ]
})

Basic Patterns

<!-- Dialog with controlled state -->
<script setup>
import { DialogRoot, DialogTrigger, DialogPortal, DialogOverlay, DialogContent, DialogTitle, DialogDescription, DialogClose } from 'reka-ui'
const open = ref(false)
</script>

<template>
  <DialogRoot v-model:open="open">
    <DialogTrigger>Open</DialogTrigger>
    <DialogPortal>
      <DialogOverlay class="fixed inset-0 bg-black/50" />
      <DialogContent class="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 bg-white p-6 rounded">
        <DialogTitle>Title</DialogTitle>
        <DialogDescription>Description</DialogDescription>
        <DialogClose>Close</DialogClose>
      </DialogContent>
    </DialogPortal>
  </DialogRoot>
</template>
<!-- Select with uncontrolled default -->
<SelectRoot default-value="apple">
  <SelectTrigger>
    <SelectValue placeholder="Pick fruit" />
  </SelectTrigger>
  <SelectPortal>
    <SelectContent>
      <SelectViewport>
        <SelectItem value="apple"><SelectItemText>Apple</SelectItemText></SelectItem>
        <SelectItem value="banana"><SelectItemText>Banana</SelectItemText></SelectItem>
      </SelectViewport>
    </SelectContent>
  </SelectPortal>
</SelectRoot>
<!-- asChild for custom trigger element -->
<DialogTrigger as-child>
  <button class="my-custom-button">Open</button>
</DialogTrigger>

Recent Updates (v2.6.0-v2.8.0)

  • New component: Rating (v2.8.0)
  • ScrollArea: Added "glimpse" scrollbar mode (v2.8.0)
  • PopperContent: Added hideShiftedArrow prop (v2.8.0)
  • TimeField: Added stepSnapping support (v2.8.0)
  • Breaking: weekStartsOn now locale-independent for date components (v2.8.0)
  • Virtualization: estimateSize accepts function for Listbox/Tree (v2.7.0)
  • Composables: useLocale, useDirection exposed (v2.6.0)
  • Select: disableOutsidePointerEvents prop on Content (v2.7.0)
  • Toast: disableSwipe prop (v2.6.0)

Resources


Token efficiency: ~350 tokens base, components.md index ~100 tokens, per-component ~50-150 tokens