Cmdk: React Command Menu (⌘K) — Setup, Examples, and Advanced Usage
Cmdk is a light, behaviour-focused library for building command palettes or command menus in React apps. If you want a searchable, keyboard-first UI (think ⌘K command palette like VS Code or Slack), cmdk gives you the building blocks without the UI baggage. This guide walks through installation, basic examples, keyboard navigation, accessibility concerns, and advanced patterns so you can ship a production-ready command menu.
What is cmdk and when to use a React command palette?
At its core, cmdk is a headless-ish library — it provides the state, keyboard handling, and ARIA-friendly patterns for a command palette while letting you control the rendering. That makes it great for apps that need a fast way to surface actions, navigate routes, or trigger features via keyboard.
Use a React command palette when your product benefits from keyboard-first interactions (power users, complex UIs, admin panels, editors). A good command menu reduces context switching, surfaces actions quickly, and makes navigation discoverable via search rather than nested menus.
Cmdk focuses on the essentials: performant filtering, keyboard navigation, and flexible composition. It complements UI frameworks — you can style it with Tailwind, Chakra, Material, or plain CSS.
Installation and getting started
Installing cmdk is straightforward. If you use npm or yarn, add the package and any styling you prefer. Example:
npm or yarn commands belong in your terminal, not in your bundle; keep them in your README:
npm install cmdk
# or
yarn add cmdk
Then import the components into your React component and render a basic command menu. The library gives you components (root, input, list, item) and hooks to control open/close and selection.
Basic example: a searchable command menu
Below is a minimal conceptual snippet (pseudo-JSX) to illustrate the structure: cmdk provides the semantics; you provide markup and styling.
{`
navigate('/dashboard')}>Go to Dashboard
openModal('new')}>New Item
`}
Focus management and keyboard shortcuts (like opening with Ctrl/Cmd+K) are handled by the library or a small wrapper. The input filters the list, and keyboard navigation (arrow keys, Enter, Esc) is wired through the components.
Make the menu searchable by wiring the input value to the list filtering. For fuzzy matching, add a lightweight filter like fuse.js — but for many apps, simple case-insensitive substring filtering is plenty fast.
Keyboard navigation, shortcuts, and accessibility
Keyboard-first UX is the whole point: support ⌘K (or Ctrl+K on Windows), arrow navigation, Home/End, and Esc to close. Cmdk components emit keyboard events and maintain focus; your job is to ensure your handlers don't fight the library.
Accessibility (ARIA) matters: ensure list items are role="option" or proper ARIA patterns, that the input has aria-label, and that focused items are announced. Use aria-selected on active items and aria-activedescendant when appropriate.
Test with screen readers and keyboard-only navigation. If you need a checklist: focus trapping when open, return focus to trigger on close, visible focus styles, and announcements for empty results.
Advanced usage and customization
Cmdk is intentionally composable. Common advanced customizations include nested groups, dynamic sections (e.g., recent items), command history, and action previews. Because rendering is yours, you can embed icons, badges, or keyboard hint chips next to items.
Performance: if you have large datasets, virtualize the list (e.g., react-virtual or similar) and debounce input filtering. Keep filtering client-side for small sets; for huge or remote data, switch to server-side search with incremental results.
State sync and routing: for actions that navigate, call your router directly (React Router, Next.js router). For global shortcuts, register a top-level listener that opens the cmdk root; ensure it respects form inputs and modal contexts so you don't interrupt typing.
Best practices and pitfalls
Keep command names short and scannable. Use verbs for actions ("Create report", "Open settings") and nouns for navigation. Expose aliases or synonyms to improve discoverability (e.g., "new", "create", "add").
Avoid overloading the palette with every UI action; prioritize high-value or frequent actions. Too many options defeat the purpose.
Pay attention to mobile: command palettes are primarily keyboard tools — provide alternate UI affordances on touch devices, and consider showing the palette as a full-screen modal with a prominent input.
Useful resources and links
For further reading and code examples, see the hands-on tutorial on building command menus: cmdk tutorial. Package details and releases are available on npm: cmdk. For React fundamentals and routing patterns, consult the React docs. For accessible patterns, the WAI-ARIA guide is a must-read: WAI-ARIA.
Troubleshooting checklist
- Shortcut not opening? Check global listener scope and whether inputs are preventing default.
- Focus jumps or is lost? Ensure focus is returned to the trigger and you don't re-render the root unnecessarily.
- Filtering slow with many items? Debounce input and consider remote search or virtualization.
Conclusion
Cmdk gives you the building blocks to implement a robust React command palette: searchable menu, keyboard navigation, accessibility scaffolding, and composability. With a small amount of code you can add a powerful, efficient command menu to your app, keyed to ⌘K for power users and discoverable for everyone else.
If you want a ready path forward: install the package, follow the basic example, and progressively enhance with fuzzy search, virtualized lists, and grouped commands.
Now go implement that ⌘K menu — your power users will thank you, and your mouse might finally get a nap.
FAQ
How do I install cmdk in a React project?
Install via npm or yarn (npm install cmdk or yarn add cmdk), then import the components into your component and render the root, input, list and items. See the package page on npm and the tutorial for example code.
How can I trigger the menu with ⌘K (or Ctrl+K)?
Register a global keyboard listener that opens the cmdk root on keydown for Meta+K (Command) or Control+K. Ensure the listener ignores typing in inputs and respects platform modifiers.
Is cmdk accessible for screen readers?
Yes—cmdk provides patterns for focus and keyboard navigation, but you must supply ARIA attributes (labels, roles, aria-selected) and test with screen readers. Follow WAI-ARIA guidelines and test keyboard-only flows.
Semantic core (keyword clusters)
Main keywords:
- cmdk
- cmdk React
- cmdk command menu
- React command palette
- React ⌘K menu
- React command menu component
- React command palette library
Supporting keywords:
- cmdk installation
- cmdk setup
- cmdk tutorial
- cmdk example
- cmdk getting started
- cmdk setup
- cmdk advanced usage
- cmdk getting started
- React searchable menu
- React keyboard navigation
- React searchable menu component
- searchable command palette
LSI / related:
- command menu
- command palette
- command palette library
- keyboard shortcuts
- keyboard navigation
- accessible command palette
- aria for command menu
- fuzzy search
- virtualized command list
- ⌘K shortcut
- Ctrl+K
- headless UI
- command palette examples
Long-tail / intent-driven queries:
- how to implement cmdk in React
- how to open command palette with ⌘K
- cmdk installation tutorial
- React command menu best practices
- accessible command palette with cmdk
Key references
- cmdk — npm package (installation & releases)
- cmdk tutorial — practical build guide
- React docs — foundational guidance
- WAI-ARIA — accessibility patterns
