Skip to main content
You are viewing Pre-Alpha documentation.
Vuetify0 Logo

Composables

Composables are the foundation of v0. They provide headless logic that you can use directly or through wrapper components.

Edit this page
Report a Bug
Copy Page as Markdown
IntermediateJan 11, 2026

Composables vs Components

Both approaches use the same underlying logic:

ts
// Direct composable usage
const selection = createSelection({ multiple: true })
selection.register({ id: 'a', value: 'Apple' })
selection.select('a')
vue
<template>
  <Selection.Root v-model="selected" multiple>
    <Selection.Item value="Apple">Apple</Selection.Item>
  </Selection.Root>
</template>

When to Use Each

Use Composables WhenUse Components When
Need full control over renderingWant declarative templates
Building custom abstractionsStandard UI patterns
Non-DOM contexts (stores, workers)Accessibility attrs needed
Maximum flexibilityFaster development
Tip

Components and composables are interchangeable. Every component uses a composable internally—you can always drop to the composable for more control.

Ask AI
How do I choose between composables and components for my use case?

Categories

Foundation

Factories that create other composables:

ComposablePurpose
createContextType-safe provide/inject
createTrinity[use, provide, context] tuple
createPluginVue plugin factory

Registration

Collection management primitives:

ComposablePurpose
createRegistryBase collection with lookup
createTokensDesign token aliases
createQueueTime-based queue
createTimelineUndo/redo history

Selection

State management for selection patterns:

ComposablePurpose
createSelectionMulti-select base
createSingleRadio, tabs, accordion
createGroupCheckboxes, tri-state
createStepWizard, stepper, carousel

Forms

Form state and validation:

ComposablePurpose
createFormValidation, dirty tracking

Reactivity

Reactive proxy utilities:

ComposablePurpose
useProxyModelv-model bridge
useProxyRegistryRegistry to reactive object

Plugins

App-level features installed via app.use():

ComposablePurpose
useThemeDark/light mode
useLocalei18n, RTL
useBreakpointsResponsive queries
useStoragePersistent state

Utilities

Standalone helpers:

ComposablePurpose
useFilterArray filtering
usePaginationPage navigation
useVirtualVirtual scrolling

Usage Patterns

Direct Factory Call

For standalone instances:

ts
import { createSelection } from '@vuetify/v0'

const tabs = createSelection({ multiple: false })
tabs.register({ id: 'home', value: 'Home' })
tabs.register({ id: 'about', value: 'About' })
tabs.select('home')

Context Injection

For component tree sharing:

ts
// Parent
import { createSelectionContext } from '@vuetify/v0'

const [useTabSelection, provideTabSelection] = createSelectionContext({
  namespace: 'tabs',
  multiple: false,
})
provideTabSelection()

// Child
const selection = useTabSelection()
selection.select('home')

Plugin Installation

For app-wide singletons:

main.ts
import { createApp } from 'vue'
import { createThemePlugin } from '@vuetify/v0'

const app = createApp(App)
app.use(
  createThemePlugin({
    default: 'light',
    themes: { light: {...}, dark: {...} },
  }),
)

Composing Composables

Build complex behavior by combining primitives:

composables/useDataTable.ts
import { createSelection, createFilter, createPagination } from '@vuetify/v0'

// Filterable, paginated selection
const items = ref([...])
const query = ref('')

const filter = createFilter()
const { items: filtered } = filter.apply(query, items)

const pagination = createPagination({
  size: () => filtered.value.length,
  itemsPerPage: 10,
})
const selection = createSelection({ multiple: true })

// Visible items with selection state
const visibleItems = computed(() => {
  const start = pagination.pageStart.value
  const end = pagination.pageStop.value
  return filtered.value.slice(start, end)
})

TypeScript

All composables are fully typed. The value type is inferred from registration:

ts
interface MyItem {
  id: string
  label: string
}

const selection = createSelection()
selection.register({ id: '1', value: { id: '1', label: 'First' } as MyItem })

// Type-safe access via ticket
const ticket = selection.get('1')
ticket?.value // MyItem
Ask AI
Which composables should I use for a data table with filtering and pagination?

© 2016-1970 Vuetify, LLC
Ctrl+/