{"id":50378866,"url":"https://github.com/yvng-jie/vue-cmdk","last_synced_at":"2026-05-30T11:01:03.816Z","repository":{"id":361363298,"uuid":"1254163063","full_name":"yvng-jie/vue-cmdk","owner":"yvng-jie","description":"⌘K — Fast, composable, unstyled command palette for Vue 3","archived":false,"fork":false,"pushed_at":"2026-05-30T09:50:58.000Z","size":57,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T10:22:15.154Z","etag":null,"topics":["cmdk","command-palette","keyboard","menu","vue","vue-component","vue3"],"latest_commit_sha":null,"homepage":"https://yvng-jie.github.io/vue-cmdk/","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yvng-jie.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T08:05:59.000Z","updated_at":"2026-05-30T09:51:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/yvng-jie/vue-cmdk","commit_stats":null,"previous_names":["yvng-jie/vue-cmdk"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/yvng-jie/vue-cmdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvng-jie%2Fvue-cmdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvng-jie%2Fvue-cmdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvng-jie%2Fvue-cmdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvng-jie%2Fvue-cmdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yvng-jie","download_url":"https://codeload.github.com/yvng-jie/vue-cmdk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yvng-jie%2Fvue-cmdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33689564,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmdk","command-palette","keyboard","menu","vue","vue-component","vue3"],"created_at":"2026-05-30T11:00:26.284Z","updated_at":"2026-05-30T11:01:03.754Z","avatar_url":"https://github.com/yvng-jie.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/v/vue-command-kit?color=blue\u0026label=version\" alt=\"npm\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/vue-3.4%2B-brightgreen\" alt=\"vue\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/license-MIT-blue\" alt=\"license\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/bundle-3.4kB_gzip-green\" alt=\"size\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003e⌘K — vue-cmdk\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eA fast, composable, unstyled command palette for Vue 3.\u003c/b\u003e\u003cbr\u003e\n  Press \u003ckbd\u003e⌘K\u003c/kbd\u003e and take control.\n\u003c/p\u003e\n\n---\n\n## 🧠 Inspiration\n\nThis project is heavily inspired by two great projects:\n\n| Project | Author | Description |\n| --- | --- | --- |\n| [`vue-command-palette`](https://github.com/xiaoluoboding/vue-command-palette) | [@xiaoluoboding](https://github.com/xiaoluoboding) | The first composable command palette for Vue, with 590 ★ |\n| [`cmdk`](https://github.com/pacocoursey/cmdk) | [@pacocoursey](https://github.com/pacocoursey) | Fast, unstyled command menu React component (10k+ ★) |\n\n### Why another one?\n\n[`vue-command-palette`](https://github.com/xiaoluoboding/vue-command-palette) pioneered the ⌘K experience for Vue. Big thanks to [@xiaoluoboding](https://github.com/xiaoluoboding) for the original idea and work 🙌\n\nHowever, the project has been **inactive since September 2023** — 9 issues remain unanswered, no dependencies have been updated in years, and the bundle size is 28 kB. The Vue ecosystem deserves a **well-maintained, lightweight alternative** that keeps up with modern standards.\n\n**vue-cmdk** is built to fill that gap: same compound component API, zero dependencies, half the size, with full TypeScript support and a commitment to ongoing maintenance.\n\n### vs vue-command-palette (legacy reference)\n\n| Feature          |  `vue-command-palette`   |  `vue-cmdk`   |\n| ---------------- | :----------------------: | :-----------: |\n| 📦 Bundle (min)  |         28.2 kB          |  **11.8 kB**  |\n| 📦 Bundle (gzip) |          9.6 kB          |  **3.4 kB**   |\n| 🔍 Search        |   fuse.js (extra dep)    | **Built-in**  |\n| 📋 TypeScript    |         Partial          |   **Full**    |\n| 🔄 Async items   |            ❌            |      ✅       |\n| 🧩 Custom filter |            ❌            |      ✅       |\n| 🔒 Focus trap    |            ❌            |      ✅       |\n| 🧹 Dependencies  | 3 (fuse.js, nanoid, ...) |     **0**     |\n| 🔧 Maintenance   |  ❌ Inactive since 2023  | ✅ **Active** |\n\n---\n\n## ✨ Features\n\n- **🧩 Compound component API** — `\u003cCommand.Dialog\u003e`, `\u003cCommand.List\u003e`, `\u003cCommand.Item\u003e`, etc.\n- **💄 Unstyled** — Bring your own CSS, zero opinions, full design control\n- **🔍 Built-in search** — Fast case-insensitive filtering with keyword matching\n- **⌨️ Keyboard-first** — Arrow keys, Enter, Escape — all built-in, no config needed\n- **📦 Tiny** — 3.4 kB gzipped, **zero runtime dependencies** (peer: `vue` only)\n- **🎯 TypeScript** — Full type inference and declaration files\n- **🔄 Dynamic items** — Pass items as a reactive array, swap anytime\n- **🛠 Custom filter** — Provide your own filter function\n- **♿ Accessible** — ARIA attributes, focus trap, `aria-live` region\n\n## 📊 Comparison with React cmdk\n\n`vue-cmdk` is a Vue 3 port inspired by the excellent [`cmdk`](https://github.com/pacocoursey/cmdk) (React). Below is the current feature parity status:\n\n| #   | Feature                                      |  React `cmdk`   |    `vue-cmdk`    |   Status   |\n| --- | -------------------------------------------- | :-------------: | :--------------: | :--------: |\n| 1   | `Command` root `value` / `onValueChange`     |       ✅        |        ❌        | 📋 Planned |\n| 2   | `Command` root `shouldFilter`                |       ✅        |        ❌        | 📋 Planned |\n| 3   | `Command` root `loop`                        |       ✅        |        ❌        | 📋 Planned |\n| 4   | `Command` root `label` (aria-label)          |       ✅        |        ❌        | 📋 Planned |\n| 5   | `Command.Dialog` `open` / `onOpenChange`     |    ✅ `open`    |   ✅ `visible`   |     ✅     |\n| 6   | `Command.Dialog` `container` (portal target) |       ✅        |        ❌        | 💡 Future  |\n| 7   | `Command.Input` `value` / `onValueChange`    |       ✅        | ✅ `searchQuery` |     ✅     |\n| 8   | `Command.Item` `forceMount`                  |       ✅        |        ❌        | 📋 Planned |\n| 9   | `Command.Item` `keywords`                    |       ✅        |        ✅        |     ✅     |\n| 10  | `Command.Item` `onSelect`                    |       ✅        |        ✅        |     ✅     |\n| 11  | `Command.Item` auto value from textContent   |       ✅        |        ❌        | 📋 Planned |\n| 12  | `Command.Group` `forceMount`                 |       ✅        |        ❌        | 📋 Planned |\n| 13  | `Command.Group` `heading`                    |       ✅        |        ✅        |     ✅     |\n| 14  | `Command.Separator` `alwaysRender`           |       ✅        |        ❌        | 💡 Future  |\n| 15  | `Command.Empty`                              |       ✅        |        ✅        |     ✅     |\n| 16  | `Command.Loading`                            |       ✅        |        ✅        |     ✅     |\n| 17  | `useCommandState()` state selector           |       ✅        |        ❌        | 📋 Planned |\n| 18  | **Nested items / Pages**                     |  ✅ (pattern)   |        ❌        | 📋 Planned |\n| 19  | **Built-in search / filtering**              |       ✅        |        ✅        |     ✅     |\n| 20  | **Custom filter function**                   | ✅ (rank-based) | ✅ (item-based)  |     ✅     |\n| 21  | **Global shortcut listener**                 |   ❌ (manual)   |  ✅ (built-in)   |  ✅ Bonus  |\n| 22  | **Keyboard navigation**                      |       ✅        |        ✅        |     ✅     |\n| 23  | **Focus trap**                               |   ✅ (Radix)    |   ✅ (custom)    |     ✅     |\n| 24  | **Zero dependencies**                        |  ❌ (Radix UI)  |   ✅ (0 deps)    | ✅ Better  |\n| 25  | **TypeScript**                               |       ✅        |        ✅        |     ✅     |\n| 26  | **Unstyled**                                 |       ✅        |        ✅        |     ✅     |\n| 27  | **Bundle size (gzip)**                       |      ~7 kB      |    **3.4 kB**    | ✅ Smaller |\n\n\u003e **Legend** — ✅ Done · 📋 High/Medium priority · 💡 Low priority / Nice to have\n\n## 🚀 Install\n\n```bash\nnpm install vue-command-kit\n```\n\n## Quick Start\n\n### Simple — items prop\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\n  import { ref } from 'vue'\n  import { Command } from 'vue-command-kit'\n  import type { CommandItemData } from 'vue-command-kit'\n\n  const visible = ref(false)\n\n  const items: CommandItemData[] = [\n    { value: 'settings', label: 'Open settings', shortcut: '⌘,' },\n    { value: 'home', label: 'Go to home', shortcut: '⌘H' },\n  ]\n\n  function onSelect(item: CommandItemData) {\n    console.log('selected:', item.value)\n  }\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cbutton @click=\"visible = true\"\u003eOpen (⌘K)\u003c/button\u003e\n\n  \u003cCommand.Dialog\n    :visible=\"visible\"\n    :items=\"items\"\n    @update:visible=\"visible = $event\"\n    @select=\"onSelect\"\n  /\u003e\n\u003c/template\u003e\n```\n\n### Advanced — custom slot content\n\n```vue\n\u003cCommand.Dialog :visible=\"visible\" @update:visible=\"visible = $event\"\u003e\n  \u003ctemplate #header\u003e\n    \u003cCommand.Input placeholder=\"Search...\" /\u003e\n  \u003c/template\u003e\n  \u003ctemplate #body\u003e\n    \u003cCommand.List\u003e\n      \u003cCommand.Group heading=\"Favorites\"\u003e\n        \u003cCommand.Item value=\"home\" label=\"Home\" /\u003e\n      \u003c/Command.Group\u003e\n    \u003c/Command.List\u003e\n  \u003c/template\u003e\n\u003c/Command.Dialog\u003e\n```\n\n### With custom filter\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\n  import { Command } from 'vue-command-kit'\n\n  function myFilter(items: CommandItemData[], query: string) {\n    // Return filtered items, or null to use default filter\n    return items.filter((item) =\u003e item.label?.includes(query))\n  }\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cCommand.Dialog\n    :filter=\"myFilter\"\n    ...\n  /\u003e\n\u003c/template\u003e\n```\n\n## 📖 API\n\n### `\u003cCommand.Dialog\u003e` Props\n\n| Prop            | Type                | Default               | Description                  |\n| --------------- | ------------------- | --------------------- | ---------------------------- |\n| `visible`       | `boolean`           | `false`               | Controlled open state        |\n| `items`         | `CommandItemData[]` | `[]`                  | Items to display             |\n| `placeholder`   | `string`            | `'Type a command...'` | Input placeholder            |\n| `filter`        | `FilterFn`          | —                     | Custom filter function       |\n| `loading`       | `boolean`           | `false`               | Show loading state           |\n| `autoFocus`     | `boolean`           | `true`                | Auto-focus input on open     |\n| `closeOnSelect` | `boolean`           | `true`                | Close dialog after selection |\n\n### `\u003cCommand.Dialog\u003e` Events\n\n| Event            | Payload           | Description                      |\n| ---------------- | ----------------- | -------------------------------- |\n| `update:visible` | `boolean`         | Emitted when visibility changes  |\n| `select`         | `CommandItemData` | Emitted when an item is selected |\n\n### Components\n\n| Component             | Description                                    |\n| --------------------- | ---------------------------------------------- |\n| `\u003cCommand.Dialog\u003e`    | Modal dialog with mask, transition, focus trap |\n| `\u003cCommand.Menu\u003e`      | Inline command menu (non-modal)                |\n| `\u003cCommand.Input\u003e`     | Search input with keyboard navigation          |\n| `\u003cCommand.List\u003e`      | Scrollable list rendering `groupedItems`       |\n| `\u003cCommand.Group\u003e`     | Group of items with heading                    |\n| `\u003cCommand.Item\u003e`      | Single selectable command item                 |\n| `\u003cCommand.Empty\u003e`     | Shown when no results match                    |\n| `\u003cCommand.Separator\u003e` | Visual separator                               |\n| `\u003cCommand.Loading\u003e`   | Loading indicator                              |\n\n### `CommandItemData`\n\n```ts\ninterface CommandItemData {\n  value: string\n  label?: string\n  keywords?: string[]\n  shortcut?: string\n  group?: string\n  disabled?: boolean\n  icon?: Component\n  onSelect?: (item: CommandItemData) =\u003e void\n}\n```\n\n### `useCommandMenu()` Composable\n\n```ts\nimport { useCommandMenu } from 'vue-command-kit'\nimport type { UseCommandMenuReturn, FilterFn } from 'vue-command-kit'\n\nconst menu: UseCommandMenuReturn = useCommandMenu(customFilter?)\nmenu.items.value = [...]\nmenu.open()\nmenu.close()\nmenu.toggle()\n```\n\n### Keyboard\n\n| Key      | Action                                 |\n| -------- | -------------------------------------- |\n| `↑` `↓`  | Navigate items (wraps around)          |\n| `Enter`  | Select current item                    |\n| `Escape` | Close dialog                           |\n| `Tab`    | Moves focus within dialog (focus trap) |\n\n## 🤝 Contributing\n\n```bash\n# dev\npnpm dev\n\n# type check\npnpm typecheck\n\n# build\npnpm build\n```\n\nPRs and issues are welcome!\n\n## 📄 License\n\nMIT © [yvng-jie](https://github.com/yvng-jie)\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003csub\u003eMade with ❤️ for the Vue community. Thanks to \u003ca href=\"https://github.com/xiaoluoboding\"\u003e@xiaoluoboding\u003c/a\u003e for the original \u003ca href=\"https://github.com/xiaoluoboding/vue-command-palette\"\u003evue-command-palette\u003c/a\u003e.\u003c/sub\u003e\n\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyvng-jie%2Fvue-cmdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyvng-jie%2Fvue-cmdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyvng-jie%2Fvue-cmdk/lists"}