Use a shared shell over an application-owned registry
A command palette looks like search, but its main job is to initiate actions. It may navigate, change application state, open a workflow, or invoke an operation. Sam Solomon describes the practical distinction: search helps people find things, while a command palette lets them do things. That distinction brings application behavior into an interface that can otherwise look like a simple dialog.
Treat the palette as a view over a command registry. The registry stores stable command identities and the application rules needed to resolve them. The shell receives current presentation data such as label, group, scope, availability, and confirmation requirements. It renders those values, then sends the selected intent to an application-owned handler.
The shared system can own the dialog, query input, result layout, focus styling, keyboard conventions, and generic presentations for loading or empty results. It should not import domain permissions, infer the active record, call product services directly, or decide whether an operation succeeded.
Decide whether the pattern fits
Use a command palette when people repeatedly perform actions across a product and the command set is broad enough that menus and shortcuts become slow to scan. It works especially well for experienced users who know the outcome they want but may not remember where the product put it.
A palette is a poor substitute for the next obvious action. Use a visible button for an important step, ordinary navigation for a compact information architecture, and search when the main task is finding content. Search and commands can sit beside each other, but their similar inputs shouldn't obscure their different outcomes.
| Best fit | Main limitation | |
|---|---|---|
| Visible button or menu | Frequent, important, or high-consequence actions | Persistent space becomes crowded if every action is exposed |
| Navigation or search | Finding destinations, records, documents, or content | Finding an item does not define an action or its consequences |
| Keyboard shortcut | A small set of stable, frequently repeated actions | Shortcuts are hard to discover and can conflict |
| Command palette | A broad action set used across changing contexts | It is hidden by default and unsuitable as the sole route to essential work |
Keep essential routes visible
Essential navigation and actions need ordinary product controls. The palette can make those routes faster, but people still need access when they don't know the shortcut, use a touch device, encounter a conflict, or cannot operate the palette.
Assign responsibility before designing states
Start with one ownership matrix before drawing detailed screens. It keeps product policy out of the shared package and shows what every application must supply to the shell.
| Design system | Consuming application | Shared review | |
|---|---|---|---|
| Invocation | Launcher pattern, overlay structure, shortcut display | Allowed surfaces and local shortcut conflicts | Keyboard path, small-screen route, focus entry and return |
| Visual system | Tokens, typography, spacing, modes, result anatomy | Approved local exceptions and product content | Long text, localization, zoom, and narrow layouts |
| Interaction | Input behavior, active-option treatment, generic keyboard conventions | Routing, workflow handoffs, cancellation semantics | Expected sequence and observable focus behavior |
| Command definition | Field contract and rendering slots | Stable IDs, labels, aliases, groups, context, ordering inputs | Naming, discoverability, and collisions |
| Availability | Treatments for available, unavailable, hidden, and forbidden outcomes | Runtime conditions and reason codes | Whether hiding or disabling is appropriate |
| Authorization | Slots for scope, restrictions, and warnings | Policy evaluation and enforcement | Whether the resolved scope and restriction are understandable |
| Execution | Progress, partial-outcome, and completion presentation | Handlers, side effects, duplicate control, and cancellation | Expected effect and failure behavior |
| Recovery | Placement and styling for undo, retry, and support routes | Rollback, retry, reconciliation, and expiry rules | Recovery copy, ownership, and test evidence |
| Acceptance | Evidence for the isolated component boundary | Runtime evidence from a named consumer | Disposition, correction owner, and retest trigger |
Shared review connects the layers without giving them equal authority. For example, the application decides that a command is forbidden, while the design system supplies a supported way to present that result. The application defines a real undo operation; the shared component controls where its action appears.
Define the palette's visual rules upstream
Once ownership and behavior are explicit, a design kit can supply the shell's color roles, typography, spacing, focus treatment, and modes. Keep those visual decisions separate from the application registry.
Write a command record that every role can review
A mockup usually captures a label, icon, and shortcut. An implementation array may add an ID and callback. Contextual commands need more: an availability rule, permission source, consequence, confirmation policy, recovery route, visible alternative, owner, and acceptance status.
The YAML below is a fictional planning fixture, not an implementation result. Its unresolved values are deliberate. They mark the decisions and observations the product team still needs to make.
id: project.archive
label: Archive project
aliases:
- close project
- retire project
group: Project
context:
requires: [activeProjectId]
resolvedScope: "Current project: Northstar"
availability:
rule: disable_during_export
reasonCode: export_in_progress
permission:
source: project-policy-service
capability: project.archive
consequence:
tier: reversible-state-change
expectedEffect: remove_from_active_projects
confirmation:
rule: require_when_open_tasks_greater_than_zero
execution:
owner: project-commands
handler: archiveProject
recovery:
route: undo-toast
expiresAfter: unresolved
alternateAccess:
route: /projects/:projectId/settings
control: Archive project
acceptance:
namedConsumer: web-project-detail
fixture: active-project-with-two-open-tasks
declared: proposed
registered: unverified
available: unverified
invoked: unverified
completed: unverified
observed: unverified
disposition: unresolved
correctionOwner: unassigned
retestTrigger: handler_or_policy_changeFields that prevent ambiguity
- Stable identity: keep the ID separate from visible copy so labels can change without breaking permissions, analytics, or integrations.
- Copy and aliases: record the displayed language and the approved terms that can retrieve the command.
- Context and availability: state where the command applies and whether it can run under current conditions.
- Permission source: name the application authority that evaluates access at execution time.
- Consequence and confirmation: classify the effect, then apply the product's confirmation policy.
- Execution and recovery: name the handler owner, expected effect, retry or undo route, and any expiry.
- Alternate access: identify a visible route so the palette remains an accelerator.
- Evidence and retest: record the named consumer, observed status, correction owner, and changes that invalidate acceptance.
Choose visibility separately from enforcement
A disabled command can explain why an action is unavailable. Hiding may reduce clutter or avoid exposing a sensitive capability. Either presentation still requires enforcement at the application's execution boundary.
Design the shell around the record
The familiar anatomy includes an invocation affordance, query input, grouped results, an active option, metadata, shortcut hints, progress, outcome messaging, and sometimes a confirmation or detail region. Setproduct offers a deeper visual and state reference. The design-system task is to turn that anatomy into a stable component contract.
Show enough metadata to separate similar results. Depending on the command, that may include a destination, selected object, workspace, current mode, shortcut, unavailability reason, or consequence. Leave secondary details out of the result row unless they affect the choice. The confirmation step or destination interface can carry the rest.
Treat long labels, translated copy, missing shortcuts, many groups, no matches, slow remote sources, and narrow viewports as normal inputs. Document wrapping, truncation, scrolling, group persistence, and the way loading or error content changes the result region.
The shared component can define focus styling and a default interaction model. The consumer still has to choose a meaningful focus destination after closing, navigating, completing an inline action, or handing off to a form. Test that behavior in the composed interface with its real routing and content.
Make matching and ranking predictable
Ranking affects which action a person is likely to run. Rootly describes page-aware ordering, and Avery Vigolo recommends contextual information with consistent results. Use context to improve relevance, but keep the relationship among the query, visible result, and current scope understandable.
- Match visible labels first, then explicit aliases and approved metadata. A match on hidden text should still produce an understandable visible result.
- Use page, selection, or object context only when it has a clear relationship to the command. Record that context as a ranking input.
- Keep the order stable while meaningful inputs remain unchanged. Avoid random tie-breaking or unexplained reshuffling when remote results arrive.
- Decide whether unavailable commands remain visible. If shown, include a reason and block invocation. If hidden, maintain another discovery route.
- Keep local commands usable while a remote source is loading.
- Give an empty result a practical next step, such as revising the query or opening a relevant destination.
Observe retrieval with real tasks. Record whether people find the intended command, which terms return no useful result, whether identical inputs cause unexpected order changes, how often people select unavailable results, and when they switch to visible controls. Use those findings to revise labels, aliases, context rules, or ranking inputs.
Test states according to consequence
Loading, empty, error, and success cover only part of the command lifecycle. The acceptance matrix also needs authorization outcomes, confirmation, partial completion, and recovery. Test every state with concrete fixture content in a named consumer, not just generic mockups.
| Test content | Inspection criteria | Failure condition | |
|---|---|---|---|
| Closed | Named surface with launcher, shortcut, and visible alternate route | Only intended contexts invoke the palette; conflicts follow the product rule | The palette opens unexpectedly, the shortcut steals another action, or no alternate route exists |
| Open | Named context with a known initial command set | Focus enters at the documented point; scope and initial ordering are clear | Focus is lost, scope is ambiguous, or order changes without an input change |
| Querying | Labels, aliases, ties, and a hidden-term match | Matches follow the declared policy and visible text explains each result | The intended command disappears, ties reshuffle, or a hidden match looks unrelated |
| Loading | Local commands plus one delayed remote source | Pending content is identified while local actions remain usable | The whole list blocks or pending results appear as final |
| Empty | A query with no approved match | The state explains the outcome and offers a useful route forward | The user reaches a dead end or stale results remain actionable |
| Unavailable | Relevant command blocked by a current application condition | Reason and recovery route match the resolved availability response | Invocation proceeds, the reason is stale, or the recovery route is wrong |
| Forbidden | Command requested by a role without the required capability | Palette and alternate route reach the same enforced policy outcome | One route permits the action or the interface implies that visibility grants access |
| Confirmation required | Known target, scope, effect, and recovery policy | Confirmation names the actual operation and resolved scope | Copy is generic, the target is wrong, or the effect differs from the handler request |
| Executing | Handler held in progress while input is repeated | Progress is clear and duplicate behavior follows application policy | Repeated input creates an unintended duplicate or leaves controls in a false idle state |
| Partially failed | Batch fixture with successful, failed, and unresolved items | The outcome separates each category and provides reconciliation guidance | Mixed results collapse into success or unresolved items disappear |
| Completed | Authoritative completion response plus expected consumer state | The defined completion signal is recorded and the result surface shows the expected effect | The completion signal is absent, contradictory, or followed by an incorrect consumer state |
| Undo available | Completed reversible action with an active recovery window | Undo restores the promised scope and reports its own outcome | Only part of the scope returns or an undo failure is hidden |
| Undo expired | The same action after the application-defined expiry | The stale action is unavailable and another recovery route is shown when one exists | The interface offers an undo request the application will reject |
Consequence tiers belong to product policy. Navigation may run immediately. A reversible state change may use an undo window. A destructive, financial, external, or broad action may require a resolved target and explicit confirmation. The application makes that decision; the component presents it.
Confirmation and authorization answer different questions
Confirmation checks that the person intends the displayed effect. Authorization checks whether the current principal may request it. Evaluate permission at the execution boundary even if the palette already displayed an allowed state.
Preserve visible controls and device-appropriate routes
Record an alternate route for every important command. It may be a menu item, settings page, object action, or destination. Showing the path as result metadata can also teach people where the action lives outside the palette.
Small screens don't need to imitate a desktop keyboard workflow. A visible launcher may open the shared shell, or the product may present the same registry through an action sheet or navigation surface. Reusing command definitions doesn't require identical presentation on every device.
Verify one command in one named consumer
Choose a specific consumer such as web-project-detail, then follow one command from its approved record to the observed result. Keep each evidence state separate. Reviewers can then locate a gap without mistaking earlier work for runtime acceptance.
- 1
Declare the command
Approve its identity, copy, context, permission source, consequence, confirmation policy, effect, recovery, alternate access, and owners.
- 2
Confirm registration
Inspect the named consumer's registry or adapter at a recorded version. Verify that the stable ID maps to the expected metadata and handler.
- 3
Resolve availability
Load the recorded fixture and capture whether the command is available, unavailable, hidden, or forbidden, including the reason and policy source.
- 4
Invoke required routes
Use the palette and the recorded alternate route. Exercise any shortcut conflict, keyboard sequence, confirmation, and focus handoff included in scope.
- 5
Record execution completion
Capture the application-owned completion signal separately from overlay closure or a client-side message.
- 6
Inspect the effect and recovery
Check the named result surface. For a reversible command, run the actual undo or retry route and record its outcome.
- 7
Set the disposition
Accept the stated scope only when every required observation is present. Otherwise, record revise or block, assign the first divergent layer to a correction owner, and name the retest trigger.
| Evidence to record | Next question | |
|---|---|---|
| Declared | Approved command contract, owner, and version | Was that contract registered in the named consumer? |
| Registered | Stable ID, metadata, and handler mapping | What does the current context resolve? |
| Available | Visibility, enabled state, reason, and policy source for the fixture | Can the required route invoke the intended handler? |
| Invoked | Request received by the intended application path | What completion outcome did that path return? |
| Completed | Application-defined completion signal and returned outcome | Does the named result surface show the expected effect? |
| Observed | Rendered effect, focus result, failure handling, and recovery under recorded conditions | Does the evidence meet the acceptance criteria for this scope? |
| Accepted | Approver, disposition, scope, versions, open exceptions, and date | Which changes require this case to run again? |
Assign a failed case to the first layer that diverged. Missing visual behavior belongs with the relevant token or component owner. An incorrect permission result belongs with the policy or application owner. A wrong handler mapping belongs with the consumer integration. This prevents a team from fixing the visible symptom while leaving the originating fault in place.
Useful retest triggers include changes to the command record, registry, handler, permission policy, routing, ranking inputs, shared component, shortcut mapping, or consumer composition. Store the trigger with the evidence so reviewers know when the acceptance has expired.
Apply Identity Forge at the visual boundary
Identity Forge can supply the palette's upstream visual system: semantic light and dark color tokens, typography, spacing, layout guidance, motifs, DESIGN.md, and shadcn, Tailwind, or DTCG exports. These artifacts can help a coding agent or development team keep the shell consistent with the surrounding product.
The consuming project still owns its command registry, context rules, permission checks, handlers, confirmation policy, undo behavior, accessibility evaluation, and runtime evidence. Start with the highest-consequence command already reused across multiple routes. Complete its record and test it in one named consumer before expanding the registry.
Distinct command palette design questions
Is a command palette the same as search?
No. Search primarily finds content or destinations, while a command palette initiates actions. A product can place them beside each other or make search one command, but the interface should make the resulting behavior clear.
Should unavailable commands be hidden or disabled?
Use a disabled result when knowing the command exists helps someone understand the product and the interface can give an accurate reason. Hide it when disclosure is inappropriate or the result would be irrelevant clutter. The application must enforce authorization in either case.
Does every risky command need confirmation?
No universal rule applies. Classify the consequence in product policy, then decide whether the resolved scope, expected effect, and recovery require confirmation. Repeated confirmation for routine reversible actions can add friction without improving the decision.
What should a team implement first?
Choose one high-consequence command that already has a visible route. Define its record, alternate access, state expectations, correction owner, and named-consumer evidence before adding more commands.
Sources
- Command Palette - UX Patterns: This guide covers selection criteria, implementation risks, interface states, testing, and measurement for command palettes.
- Command Palette UI Design, 8 States and 10 Teardowns: This guide provides the visual anatomy, interaction rules, state coverage, and product examples used as the presentation baseline.
- Command Palette: Lightning Fast Navigation with a Single Keyboard Command: Rootly describes a page-aware command palette that orders results according to the current product context.
- Designing Command Palettes: Sam Solomon distinguishes action-oriented command palettes from search and discusses keyboard focus, interaction handoffs, and context awareness.
- Good design patterns: the command palette: Avery Vigolo discusses contextual metadata, hidden matching terms, predictable ordering, keyboard operation, and paths back to ordinary menus.
- cmdk in React: Build a Fast Command Palette (Setup & Examples): This tutorial demonstrates React command primitives, keyboard invocation, navigation, asynchronous search, and application-supplied items.
- ActionMenu - Primer: Primer documents action items together with loading, inactive, selection, submenu, and contextual menu variants.
- Identity Forge: Identity Forge provides design kits with semantic tokens, typography, spacing, usage guidance, DESIGN.md, and implementation exports.
- Design system accessibility checklist: test the system, then retest the product: This checklist separates documented intent, isolated component evidence, and observations from a real product consumer.