pacocoursey /cmdk

Fast, unstyled command menu React component.

★ 13,060⑂ 382👁 26⑃ 134● 216▤ 12
TypeScriptCreated 2022-07-16
13,060
stars
+0+-2+50
382
forks
26
watchers
134
prs
216
issues
12
releases
–
discussions

README

⌘K  

⌘K is a command menu React component that can also be used as an accessible combobox. You render items, it filters and sorts them automatically. ⌘K supports a fully composable API How?, so you can wrap items in other components or even as static JSX.

 Install

bash
pnpm install cmdk


 Use

tsx
import { Command } from 'cmdk'

const CommandMenu = () = {
  return (
    
      
      
        No results found.

        
          a
          b
          
          c
        

        Apple
      
    
  )
}


Or in a dialog:

tsx
import { Command } from 'cmdk'

const CommandMenu = () = {
  const [open, setOpen] = React.useState(false)

  // Toggle the menu when ⌘K is pressed
  React.useEffect(() = {
    const down = (e) = {
      if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
        setOpen((open) = !open)
      }
    }

    document.addEventListener('keydown', down)
    return () = document.removeEventListener('keydown', down)
  }, [])

  return (
    
      
      
        No results found.

        
          a
          b
          
          c
        

        Apple
      
    
  )
}


 Parts and styling

All parts forward props, including ref, to an appropriate element. Each part has a specific data-attribute (starting with cmdk-) that can be used for styling.

 Command [cmdk-root]

Render this to show the command menu inline, or use Dialog to render in a elevated context. Can be controlled with the value and onValueChange props.

 Note

 Values are always trimmed with the trim() method.

tsx
const [value, setValue] = React.useState('apple')

return (
  
    
    
      Orange
      Apple
    
  
)


You can provide a custom filter function that is called to rank each item. Note that the value will be trimmed.

tsx
 {
    if (value.includes(search)) return 1
    return 0
  }}
/


A third argument, keywords, can also be provided to the filter function. Keywords act as aliases for the item value, and can also affect the rank of the item. Keywords are trimmed.

tsx
 {
    const extendValue = value + ' ' + keywords.join(' ')
    if (extendValue.includes(search)) return 1
    return 0
  }}
/


Or disable filtering and sorting entirely:

tsx

  
    {filteredItems.map((item) = {
      return (
        
          {item}
        
      )
    })}
  



You can make the arrow keys wrap around the list (when you reach the end, it goes back to the first item) by setting the loop prop:

tsx



 Dialog [cmdk-dialog] [cmdk-overlay]

Props are forwarded to Command. Composes Radix UI's Dialog component. The overlay is always rendered. See the Radix Documentation for more information. Can be controlled with the open and onOpenChange props.

tsx
const [open, setOpen] = React.useState(false)

return (
  
    ...
  
)


You can provide a container prop that accepts an HTML element that is forwarded to Radix UI's Dialog Portal component to specify which element the Dialog should portal into (defaults to body). See the Radix Doc

Snapshot: 2026-11-04T14:00:00Z · Data license Apache-2.0 · JSON