# Command Menu

> One shortcut to reach everything.

- Section: Interaction
- URL: https://critly.vercel.app/command-menu
- Published: 2026-10-02
- Source: https://github.com/kausthubh-coder/critly/blob/main/content/interaction/command-menu.mdx

A command menu puts every action behind one shortcut. Press Cmd+K, or Ctrl+K on
Windows, type a few letters, press Enter. Nobody has to remember where a
setting lives, only roughly what it does.

**Open it instantly, match what people mean, and show each command's shortcut
next to it.**

> **Interactive demo: Command Menu.** Open https://critly.vercel.app/command-menu to try it.

Click the window and press the shortcut, or use the search field. Arrows move,
Enter runs, Escape closes. Run "Toggle sidebar" from the menu and the footer
tells you the shortcut for next time.

## Open it instantly

The menu exists to make things fast, so it can't be slow to appear. It opens
with no animation, the cursor is already in the input, and the same shortcut
closes it. This is [hover restraint](https://critly.vercel.app/hover-restraint) again: something you open
forty times a day can't afford a fade.

Closing returns focus to the search field, and nothing in the list needs a mouse.

## Match what people mean

People don't type your label, they type their own word. Someone looking for
dark mode types "dark", not "Change theme". An exact search finds nothing, and
they decide the feature doesn't exist.

> **Interactive demo: Command Search.** Open https://critly.vercel.app/command-menu to try it.

Give every command a few keywords and match loosely against the title and the
keywords together. When a keyword matched, show it next to the result so the
match doesn't look random.

## Teach the shortcuts

A command menu is also where people learn your shortcuts. If every row shows
its keys, the tenth time someone runs "Toggle sidebar" from the menu, they press
the shortcut instead. A shortcut nobody sees never gets learned.

> **Interactive demo: Command Shortcuts.** Open https://critly.vercel.app/command-menu to try it.

Order the list for the person, not the codebase. With an empty query, show
recent commands first, then the ones that fit the current screen. Most of the
time, the thing someone wants is the thing they did a minute ago.

## Usage

**React**

```tsx
import { Command } from "cmdk";
import { useEffect, useState } from "react";

export function CommandMenu() {
  const [open, setOpen] = useState(false);

  useEffect(() => {
    const onKeyDown = (event: KeyboardEvent) => {
      if (event.key === "k" && (event.metaKey || event.ctrlKey)) {
        event.preventDefault();
        setOpen((open) => !open);
      }
    };
    document.addEventListener("keydown", onKeyDown);
    return () => document.removeEventListener("keydown", onKeyDown);
  }, []);

  return (
    <Command.Dialog open={open} onOpenChange={setOpen} label="Command menu">
      <Command.Input placeholder="Type a command" />
      <Command.List>
        <Command.Empty>No commands found.</Command.Empty>
        <Command.Item
          value="Change theme"
          keywords={["dark mode", "light mode", "appearance"]}
          onSelect={toggleTheme}
        >
          Change theme
          <kbd className="ml-auto text-xs text-muted-foreground">⌘⇧L</kbd>
        </Command.Item>
      </Command.List>
    </Command.Dialog>
  );
}
```

**Tailwind**

```html
<div
  cmdk-item
  class="flex h-8 items-center gap-2.5 rounded-lg px-2.5 text-sm data-[selected=true]:bg-muted"
>
  Change theme
  <kbd class="ml-auto text-xs text-muted-foreground">⌘⇧L</kbd>
</div>
```

Set `value` on every item. Without it, cmdk uses the item's text, so the
shortcut becomes part of what it searches and "L" starts matching "Change
theme".

## Resources

- [How to build a remarkable command palette](https://blog.superhuman.com/how-to-build-a-remarkable-command-palette/): Superhuman's rules for the pattern - one shortcut everywhere, every command, forgiving search, and context.
- [cmdk](https://github.com/dip/cmdk): The React command menu this site uses, with keyword aliases and a pluggable filter.
- [ARIA combobox pattern](https://www.w3.org/WAI/ARIA/apg/patterns/combobox/): The keyboard and screen reader behavior for an input that controls a list of options.
- [Command K bars](https://maggieappleton.com/command-bar): Maggie Appleton on where the pattern came from and why it scales better than menus.
