v1.0.0 | View in Storybook
When to use
- A power-user shortcut to access actions or destinations without navigating manually.
- Applications with a large number of actions or pages that would be impractical to surface all at once.
- When you want to support keyboard-driven workflows across the whole app.
When not to use
- Filtering a specific list or dataset on the page — use dedicated page Search.
- Selecting from a known set of options in a form — use Combobox or Select.
- Simple navigation between a small number of pages — use Tabs or nav links.
Dos and don’ts
- Do group results into categories (actions, pages, recent, etc.) an ungrouped flat list becomes hard to scan quickly.
- Do use action verbs for command labels (“Open settings”, “Create asset”, “Switch to dark mode”).
- Do show the keyboard shortcut on whatever triggers the command menu.
- Do show a meaningful empty state when no results match — “No results for…” is more helpful than a blank panel.
- Do show a loading state rather than leaving the list empty while fetching if results load asynchronously.
- Do show recent or frequently used items surfaced by default as they make the primitive significantly more useful.
- Don’t include destructive actions without a confirmation step after selection.
Often used with
Host surface uses (Dialog or Popover), Search, result list with sections; KBD chord to open; optional Empty state when no matches.
Accessibility
- Input accessible name:
<CommandInput> does not render an internal <label>. Pass an aria-label (e.g., aria-label="Search settings and actions") or aria-labelledby directly to the input element so screen readers announce its purpose upon focus.
- Accessible launcher: If the command palette is toggled via a global keybinding (e.g., ⌘K), provide an accessible, focusable button in your page layout (e.g., a header search button) so screen reader and keyboard-only users can trigger it without knowing the shortcut.
Modal context (CommandDialog)
- Accessible dialog title: When using
<CommandDialog>, ensure a <DialogTitle> node is included. If you want a visual-only search bar without a header title, wrap <DialogTitle> in a visually hidden utility class (sr-only) so screen readers still announce the modal’s name upon open.
Keyboard shortcuts (CommandShortcut)
- Screen reader pronunciation: Visual shortcut glyphs (e.g., ⌘K or ⌥P) inside
<CommandShortcut> are often skipped or read awkwardly by screen readers (e.g., “place of interest sign K”). Hide visual shortcut badges using aria-hidden="true" and provide accessible alternative text:
Rich items and grouping
- Decorative elements: If a
<CommandItem> contains icons, status dots, or user avatars, wrap those visual elements with aria-hidden="true" to prevent screen readers from cluttering the item’s primary text label.
- Group heading strings: Always pass plain, descriptive strings to
<CommandGroup heading="..."> (e.g., heading="System Settings"). Avoid passing complex JSX into the heading prop to ensure cmdk can parse and set the group’s accessible label correctly.
Visual and custom styling overrides
- Selection state contrast: When extending Tailwind styles for active item states (
data-[selected="true"]), maintain at least a 4.5:1 contrast ratio between the selected background fill and the text color.
- Focus indicators: If using
<Command> outside of a modal popover, ensure custom focus rings (focus-visible:ring-2) remain clearly visible when navigating into the input field via Tab.
Visual examples
The examples below are interactive and follow the doc site’s theming: light mode when the docs site is in light mode, and dark mode when you switch the docs site to dark mode.
Dialog
Render the Command palette inside a Dialog when it should take over the screen—typically opened with ⌘K or Ctrl+K—for app-wide action and navigation search.
Filtering
Use Command filtering when the result list narrows as the user types, helping them find actions or destinations quickly in a large catalog.
Disabled items
Show disabled items in the Command list when an action exists but is unavailable in the current context—for example, a delete action with nothing selected.
Multiple groups
Group Command results into categories—such as Actions, Pages, and Recent—so users can scan related items instead of scrolling one flat list.
Custom styling
Apply custom styling to the Command palette when it must match a branded surface or fit a constrained layout, while keeping keyboard navigation and grouping behavior intact.
Keyboard navigation
Ensure the Command palette supports arrow-key movement, Enter to select, and Escape to dismiss so power users can operate it entirely from the keyboard.
No results found
Show a no-results state in the Command palette when the query matches nothing, including the search term so users know to try different keywords.
Long list
Use the long-list Command pattern when many results are available, relying on filtering and scrollable groups to keep navigation manageable.
Async search
Use async search in the Command palette when results load from an API, showing a loading state until matches return and updating the list as the user types.
Last modified on September 16, 2026