cmdk in React — Build Fast, Accessible Command Menus (⌘K)





cmdk in React: Build Fast Command Menus (Setup & Examples)


cmdk in React — Build Fast, Accessible Command Menus (⌘K)

Cmdk is a tiny, focused React toolkit for building command palettes (the classic ⌘K/CTRL+K searchable menu). This article gives a concise technical guide: installation, core components, code examples, keyboard navigation, and advanced patterns like async search, grouping, and portals. You’ll leave with a working mental model and copy-paste-ready snippets.

Overview: What cmdk is and when to use it

Cmdk is a React-first command palette library that provides composable primitives for building searchable command menus and keyboard-driven UIs. It focuses on accessibility, keyboard navigation, and minimal styling so you can adapt it to your design system without fighting defaults.

Use cmdk when you need a lightweight, keyboard-first interface for power users: app-wide commands, contextual actions, quick navigation, or developer tools. It’s not a full UI kit—it’s bricks you compose into a command menu component that behaves predictably across platforms.

The library is intentionally unopinionated about styling and data fetching. That gives you flexibility to integrate it with your state management, server-side search, or autocomplete sources while keeping keyboard handling and focus management correct out of the box.

Installation and basic setup (cmdk installation & getting started)

Install cmdk via npm or yarn. This installs the primitives you need: Command, CommandInput, CommandList, CommandItem, and a few helpers. Paste this into your project root:

npm install cmdk
# or
yarn add cmdk

After installing, mount the command menu component near the top of your app (often in a layout or portal root). You’ll wire up the input and items, then toggle visibility with state and keyboard shortcuts (commonly ⌘K / Ctrl+K).

A minimal pattern: keep a boolean state like isOpen, render <Command> when open, and place <CommandInput> and <CommandList> inside. The built-in keyboard navigation will handle arrow keys, Enter, and Escape automatically.

Core concepts and API (cmdk React primitives)

Cmdk exposes a handful of semantic components: Command (root), CommandInput (search box), CommandList (container), CommandItem (action), CommandGroup (logical grouping), and CommandSeparator. These primitives are intentionally simple so they compose naturally with React state and effects.

Key responsibilities:

  • Command: root provider for keyboard and focus management
  • CommandInput: controlled input that filters items (you can override filtering)
  • CommandList / CommandItem: render items and handle selection

Because cmdk doesn’t impose styling, pair it with utility CSS (Tailwind), CSS-in-JS, or your component library. For accessibility, ensure focus outlines and aria roles are preserved; cmdk sets many roles for you, but custom renderers must keep semantic attributes.

Basic example — React command palette component

Below is a compact example demonstrating a toggled palette with keyboard shortcut handling and simple filtering. This is a copy-paste starting point; adapt the styling and item data to your app.

import React, {useState, useEffect} from 'react'
import { Command, CommandInput, CommandList, CommandItem } from 'cmdk'

function Palette() {
  const [open, setOpen] = useState(false)
  useEffect(() => {
    function onKey(e) {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
        e.preventDefault()
        setOpen(prev => !prev)
      }
    }
    window.addEventListener('keydown', onKey)
    return () => window.removeEventListener('keydown', onKey)
  }, [])

  return open ? (
     setOpen(false)} style={{width: 560}}>
      
      
         console.log('Open settings')}>Open settings
         console.log('Go to projects')}>Go to projects
         console.log('Create new file')}>Create new file
      
    
  ) : null
}

This example wires up the global ⌘/Ctrl+K toggle and demonstrates selection handlers. Replace console logs with router navigation or state commands as needed. Keep actions idempotent and avoid heavy synchronous work during selection to preserve perceived responsiveness.

Advanced usage patterns (cmdk advanced usage)

For apps with hundreds of commands or remote search, you’ll want to decouple filtering from the CommandInput by managing the input value in state and performing debounced lookups. Cmdk allows you to render any set of CommandItems based on your filtered results—so server-side search and caching strategies are fully compatible.

Grouping and sections are useful when commands have contexts. Use CommandGroup and separators to surface categories (Navigation, Actions, Settings). Provide small labels or badges to show keyboard shortcuts and the origin of results (local vs. remote).

Portals and layering: render the Command into a portal to avoid stacking context issues with modals, sidebars, or iframes. When you use a portal, ensure focus trap and scroll locking are considered so the palette remains accessible and predictable.

Keyboard navigation & accessibility (React keyboard navigation)

Cmdk implements roving focus, arrow navigation, type-ahead, and Home/End support out of the box. This lets you rely on CLI-like ergonomics without rolling your own focus management. A11y considerations you must still handle: visible focus styles, contrast, and screen reader announcements for remote results.

For voice search and assistive tech, avoid relying solely on placeholder text. Use aria-label or visually hidden labels for the CommandInput so screen readers announce intent. When results update from server queries, use polite live regions if the change is significant to announced content.

Keyboard shortcuts: provide a help hint (press ⌘K) and a place for users to discover other hotkeys. Consistent keyboard shortcuts and the option to rebind or disable them are a friendly touch for power users and those on different keyboard layouts.

Performance tips and patterns

Debounce remote searches (150–300ms) and cache recent queries. Render a slim set of results and use virtualization for very large lists to keep navigation snappy. Avoid heavy renders inside CommandItem; prefer memoized components or simple text nodes.

If you perform client-side fuzzy matching, prefer optimized algorithms (Fuse.js, tiny-matchers) and do computing outside render with useMemo or by precomputing searchable tokens. Keep item render paths cheap: icons, labels, and shortcuts are usually enough to guide selection.

Batch analytics and telemetry outside of the immediate selection handler to avoid blocking selection transitions. If you must run side effects on select, call them async or in a microtask so the UI remains responsive.

Integration, examples, and learning resources

Want a deeper walkthrough? A practical tutorial that shows building command menus with cmdk in React is available here: cmdk tutorial: Building command menus with cmdk in React. It demonstrates grouping, styling, and real data integration.

Official project and source code can be found on GitHub; this is the canonical reference for props, components, and updates: cmdk GitHub. Install or check the latest version on npm: cmdk on npm.

For more example-driven patterns, look for articles and community components that implement accessible styling, virtualization, and complex keyboard schemas—these examples accelerate building production-ready command palettes in React.

Semantic core (expanded keyword clusters)

Primary (target):
cmdk, cmdk React, cmdk installation, cmdk tutorial, React command palette, React command menu component, React ⌘K menu

Secondary (high/medium frequency):
command menu, command palette library, React searchable menu, cmdk setup, cmdk example, React keyboard navigation, cmdk getting started, cmdk advanced usage

Clarifying & LSI phrases:
searchable command menu, ⌘K command palette, command palette accessibility, keyboard-first UI, command palette components, CommandInput CommandList CommandItem, server-side search debounce, fuzzy search React, command menu grouping

On-page SEO and microdata (FAQ Schema)

Add the following JSON-LD to the page head (or body) to enable FAQ rich results. This file already includes the three-key FAQ below.

FAQ — top 3 user questions

1. What is cmdk and when should I use it?

Cmdk is a React toolkit of small primitives for building command palettes (the ⌘K UI). Use it when you need fast, keyboard-first navigation and action invocation—great for developer tools, admin panels, and power-user features in web apps.

2. How do I install cmdk and add a basic ⌘K menu?

Install via npm or yarn (npm install cmdk). Create an open-state for the palette, handle a global keydown for ⌘/Ctrl+K to toggle it, and render Command with CommandInput and CommandList. Use CommandItem onSelect handlers to execute actions or navigate.

3. Can cmdk handle remote search and large result sets?

Yes. Manage the input value in state, perform debounced server queries, cache results, and render filtered CommandItems. For very large lists, apply virtualization and ensure selection handlers remain fast and non-blocking.

Backlinks and further reading