Installation
pnpm dlx shadcn-vue@latest add "https://ui.stackhacker.io/r/model-picker.json"
Usage
<script setup lang="ts">
import { ref } from 'vue'
import { ModelPicker, type ModelPickerModel } from '@/components/model-picker'
const selected = ref('openai/gpt-5-nano')
const models: ModelPickerModel[] = [
{ value: 'openai/gpt-5-nano', label: 'GPT-5 Nano', provider: 'OpenAI' },
{ value: 'anthropic/claude-haiku-4.5', label: 'Claude Haiku 4.5', provider: 'Anthropic' }
]
</script>
<template>
<ModelPicker v-model="selected" :models="models" />
</template>App-Owned Model State
ModelPicker is controlled UI. Your app owns model availability, provider metadata, persistence, cookies or local storage, pricing, and runtime selection behavior.
Pass model options through the models prop and handle update:modelValue through v-model. Use scoped slots for provider icons or custom option rendering instead of Nuxt Icon strings or hardcoded provider lists.
Examples
Controlled picker
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
modelValue | string | — | Controlled selected model value. |
models | ModelPickerModel[] | null | [] | Models supplied by your app. |
placeholder | string | 'Select model' | Trigger placeholder when selected value is unknown. |
searchPlaceholder | string | 'Search models...' | Search input placeholder. |
emptyLabel | string | 'No models found.' | Empty state text. |
disabled | boolean | false | Disable the picker. |
align | 'start' | 'end' | 'start' | Align the menu against the trigger. |
class | string | — | Additional CSS classes for the root element. |
Types
interface ModelPickerModel {
value: string
label: string
description?: string
provider?: string
disabled?: boolean
}Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | [value: string] | Emitted when a selectable model is chosen. |
Slots
| Slot | Props | Description |
|---|---|---|
icon | { model?: ModelPickerModel } | Optional icon for the selected model and option rows. |
selected | { model?: ModelPickerModel } | Replace trigger selected-model content. |
option | { model: ModelPickerModel, selected: boolean } | Replace option row content. |
empty | { query: string } | Replace empty state content. |

