Introduction
A small command palette for Vue 3 that works well from the keyboard and with screen readers.
vue-cmdk-palette gives a Vue 3 app the ⌘K menu people know from editors and dashboards: one field, a filtered list, and every action reachable without the mouse. The npm package is vue-cmdk-palette, and the docs are for that package.
The current version is 1.2.2. See the changelog for what each release changed.
<script setup lang="ts">
import { ref } from 'vue'
import { CommandPaletteDialog, type Command } from 'vue-cmdk-palette'
const open = ref(false)
const last = ref('nothing yet')
const run = (label: string) => () => {
last.value = label
}
const commands: Command[] = [
{ kind: 'action', id: 'new-file', label: 'New file', perform: run('New file') },
{ kind: 'action', id: 'save', label: 'Save', shortcut: 'mod+s', perform: run('Save') },
{ kind: 'action', id: 'close', label: 'Close tab', perform: run('Close tab') },
]
</script>
<template>
<button type="button" class="button" @click="open = true">Open the minimal palette</button>
<p class="note">Last command: {{ last }}</p>
<!-- The page already owns ⌘K, so this one opens from the button only. -->
<CommandPaletteDialog v-model:open="open" :commands="commands" :hotkey="false" :recents="false" />
</template>

There are two ways to use it. <CommandPaletteDialog> is a ready-made modal with the hotkey, focus handling and scroll lock already wired. If you’d rather write your own markup, the headless useCommandPalette() composable gives you the state and the ARIA attributes and leaves the rendering to you.
What’s in it:
- No runtime dependencies. Vue
^3.5is a peer dependency, and the bundle is about 11 kB minified and gzipped. - Plain substring search over labels, keywords and hints, with typographic quotes and dashes folded to their keyboard forms.
- Nested pages, loaded synchronously or from a promise.
- Scope chips with optional prefixes such as
>for commands. - Recents ranked by frequency and recency, stored in
localStorageor through your own adapter. - The WAI-ARIA combobox and listbox pattern, with a live region that announces the result count.
- Unstyled unless you import the theme, which is built on
--cmdk-*CSS variables with light and dark modes.
Getting started
Install the package and render your first palette.
Examples
Minimal, compact and full palettes, plus two custom themes, with their source.
Styling
Theme variables, data attributes, and going fully custom.
Reference
Every prop, event, slot and composable option.
FAQ
Does it need any other packages?
No. The package has no runtime dependencies. Vue ^3.5 is a peer dependency, so your app supplies it.
Is it accessible?
The markup follows the WAI-ARIA combobox and listbox pattern, focus returns to where it was when the dialog closes, and a live region announces the result count. The browser tests run an axe-core check in both themes.
Can I translate the text?
Yes. Every built-in string is in labels. Pass any subset of them, and the rest keep the English defaults.
Does it work on the server?
The package has a server-rendering test suite. Check your framework’s setup in your own project before you ship.
Can I restyle it?
Yes. The optional theme is built on --cmdk-* CSS variables, and every part has a data-cmdk-* attribute to target. You can also skip the theme and write every rule yourself.