What is a command palette?
A command palette is a search-driven menu, opened with a keyboard shortcut like Cmd+K or Ctrl+K, that lets users navigate, find records and run actions by typing a few letters. Code editors made it popular, and keyboard-first SaaS tools adopted it for the same reason: once a product has more features than its navigation can show, typing is faster than clicking.
It's one pattern within our guide to web app UI design, and it works best as an extra layer. Users who never press Cmd+K must still be able to reach everything through visible navigation. A command palette rewards people who learn it, and it shouldn't punish people who don't.
Does your product need a Cmd+K menu?
Your product needs a Cmd+K menu when users return daily, the app has many destinations or records, and a meaningful share of work is repetitive. It's usually overkill for simple tools people visit once a week.
Pros
- Fast access to deep pages and records without hunting through menus
- One place to run actions (create, assign, switch workspace) from anywhere
- Teaches keyboard shortcuts by showing them next to each command
- Scales as features grow, without crowding the navigation
Cons
- Invisible to users who don't know it exists
- Adds real engineering work: search, ranking, permissions and performance
- A weak palette (slow, badly ranked) trains users to ignore it
- Can become a dumping ground for features that lack a proper home
Make it discoverable: show a "Search or jump to" button with the shortcut hint in the header or sidebar, so mouse users can open it too and learn the shortcut by seeing it.
What should a command palette design include?
A command palette should include three kinds of results: places to go, things to find and actions to run. Mixing them in one list is the point, but they need clear grouping so users can scan.
Result type | Examples | Design notes |
|---|---|---|
Navigation | Go to Settings, Go to Billing, Open Reports | Short labels, a page icon, the route's shortcut if it has one |
Records | Projects, contacts, tickets, documents | Show a secondary line (owner, status) to tell similar names apart |
Actions | Create project, Invite teammate, Toggle dark mode | Start with a verb, show the shortcut, confirm destructive actions |
Contextual actions | Assign this ticket, Change status | Only show when relevant to the current page or selection |
Help | Search docs, Contact support, Keyboard shortcuts | Keep at the bottom; useful as a fallback when nothing matches |
Nested commands keep the list short. "Change status" can open a second level with the status options, with a breadcrumb in the input and Backspace to go back. Respect permissions everywhere: never show an action the user can't perform.
What should the palette show before the user types?
Before the user types, the palette should show recent items and the most likely next actions, not an empty box or the full command list. This empty query state is where most palettes are weakest and where good ones earn daily use.
- Recent: the last few records and pages the user opened, so Cmd+K then Enter returns to recent work.
- Suggested for this page: contextual actions based on where the user is, like "Assign to me" on a ticket.
- Common actions: two or three creation commands the user runs most.
- A hint line: a short note on what can be searched, such as "Search projects, people and settings."
When a query returns nothing, apply the no-results principles from our guide to empty state design: echo the query, suggest a docs search, and offer to create the thing if that makes sense ("Create project 'Atlas'").
How should command palette results be ranked?
Rank results by how well they match the query first, then by the user's own recency and frequency, then by context. A palette that ranks alphabetically, or by object type, puts the right answer fifth, and users stop trusting it.
Match quality
Exact and prefix matches on the label beat matches in the middle of a word, which beat fuzzy matches. Matching the first letters of words ("np" for New project) is worth supporting.
Aliases and keywords
Give commands synonyms: "billing" should find Invoices and Payment methods, "dark" should find Theme. These are copy decisions.
Recency and frequency
Boost items the user opened or ran recently and often. This is what makes the palette feel personal.
Context
Boost actions that apply to the current page or selection, and records in the current workspace.
Stable ordering
Once results appear, avoid reshuffling them as slow server results arrive. Append new groups instead of reordering ones the user is about to select.
Our guide to loading state design explains how to keep the list stable while results stream in. If your app already has advanced filters, the palette can also apply them by name, a pattern from our filter UX design guide.
How do you build a command palette with cmdk in React?
cmdk is an unstyled React component library for command menus. It provides the input, list, groups, items, empty state and dialog, and it handles filtering, ranking hooks and keyboard navigation, so your team spends its time on content and styling. shadcn/ui's Command component is built on top of it.
Implementation notes: cmdk structure, filtering and server results
The basic structure is a Command root containing an input, a list, an empty message and one or more groups of items. Wrapping it in cmdk's dialog component gives you a modal palette; you add the Cmd+K and Ctrl+K listener yourself with a keydown handler at the app level.
Each item has a value used for matching, and can take extra keywords, which is where your aliases go. cmdk's built-in filter scores and sorts items by match, and you can pass a custom filter function to add your own weighting, for example boosting recent items.
For server-side search, cmdk's should-filter option on the root turns off built-in filtering, so you can render results from your API as items and debounce the query. If you mix local and server results, filter the local commands yourself (or with the same scoring) so they stay instant.
Nested pages are a pattern rather than a feature: keep a stack of pages in state, render different groups per page, and pop the stack on Backspace when the input is empty. Style it with your design tokens so it matches light and dark themes.
Accessibility comes partly from the library and partly from you: the palette needs a label, announced result counts and focus returned to the trigger on close. Our accessible web app design checklist lists the keyboard behavior users expect from this pattern.
Should a command palette include AI?
A command palette can include AI when typed intent goes beyond what keyword search handles, such as "show overdue invoices from last month" or "draft a reply to this ticket." Add it as a clearly labelled option at the bottom of the results ("Ask AI: ..."), not as a replacement for fast, exact matches.
Keep deterministic commands deterministic. If a user types "settings", they want Settings instantly, not a generated answer. When the AI path runs, show what it will do before it does it, especially for actions with side effects. Our guide to AI product UX covers previews, approvals and undo for AI actions.
