---
title: Command
description: A searchable command menu with keyboard navigation.
icon: command
author:
  name: pacocoursey
  url: https://github.com/pacocoursey
search:
  keywords: [command palette, cmdk, spotlight]
mode: wide
---

<PoweredBy
  packages={[
    { name: 'Shadcn UI', url: 'https://ui.shadcn.com/docs/components/command' },
    { name: 'cmdk', url: 'https://cmdk.paco.me/' },
    { name: 'Lucide', url: 'https://lucide.dev/' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/command
```

<ComponentPreview name="command-demo" />

## When to use

Use this decision tree to determine when to use the Command component:

```mermaid
graph TD;
    A[❓ Need searchable interface?] --> B{What type of interaction?};
    B --> C[✅ Command palette/search];
    B --> D[✅ Searchable dropdown];
    B --> E[⚠️ Simple selection];

    C --> F[❓ Trigger method?];
    D --> G[✅ Use as Combobox base];
    E --> H[⚠️ Use Select instead];

    F --> I["✅ Keyboard shortcut (Cmd+K)"];
    F --> J[✅ Button click];

    I --> K[✅ Use CommandDialog];
    J --> L[ℹ️ Use inline Command];

    K --> M[❓ Many command groups?];
    L --> N[❓ Need shortcuts display?];

    M --> O[✅ Use CommandGroup + CommandSeparator];
    M --> P[ℹ️ Single CommandGroup];

    N --> Q[✅ Add CommandShortcut];
    N --> R[ℹ️ Basic CommandItem];

    O --> S[❓ Simplified API needed?];
    P --> S;
    Q --> S;
    R --> S;

    S --> T[✅ Use SimpleCommand component];
    S --> U[ℹ️ Use full Command composition];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class C,D,G,I,J,K,O,Q,T recommended;
    class E,H discouraged;
    class A,B,F,M,N,S decision;
    class L,P,R,U neutral;
```

## Usage

```tsx
import {
  Command,
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
  CommandShortcut,
  CommandSub,
  CommandSubTrigger,
  CommandSubContent,
  SimpleCommand,
} from '@/components/ui/command';
```

```tsx
<Command>
  <CommandInput placeholder="Type a command or search..." />
  <CommandList>
    <CommandEmpty>No results found.</CommandEmpty>
    <CommandGroup heading="Suggestions">
      <CommandItem>Calendar</CommandItem>
      <CommandItem>Search Emoji</CommandItem>
      <CommandItem>Calculator</CommandItem>
    </CommandGroup>
    <CommandSeparator />
    <CommandGroup heading="Settings">
      <CommandItem>Profile</CommandItem>
      <CommandItem>Billing</CommandItem>
      <CommandItem>Settings</CommandItem>
    </CommandGroup>
  </CommandList>
</Command>
```

### Surface variants

Use `variant="standalone"` for the rounded, bordered panel shown in the examples instead
of adding border, radius, and shadow classes at the call site. The default `elevated`
variant retains its existing, smaller corner radius. `minimal` and `dialog` omit the
elevated border and shadow recipe. `CommandDialog` selects `dialog` for its inner command.

## Examples

### Simple Command

A higher-level component that provides a simplified API for creating command menus.

<ComponentPreview name="command-simple-demo" />

### SimpleCommand Props

| Prop           | Type                             | Default                         | Description                        |
| -------------- | -------------------------------- | ------------------------------- | ---------------------------------- |
| `placeholder`  | `string`                         | `"Type a command or search..."` | Input placeholder text             |
| `emptyMessage` | `string`                         | `"No results found."`           | Message shown when no results      |
| `groups`       | `Array<CommandGroup>`            | -                               | Array of command groups (required) |
| `size`         | `'sm' \| 'md' \| 'lg' \| 'full'` | `'md'`                          | Command size variant               |
| `className`    | `string`                         | -                               | Additional CSS classes             |

### CommandGroup Interface

```tsx
interface CommandGroup {
  heading?: string;
  items: CommandItem[];
}

interface CommandItem {
  icon?: React.ReactNode;
  label: string;
  shortcut?: string;
  disabled?: boolean;
  onSelect?: () => void;
}
```

### Usage

```tsx
import { SimpleCommand } from '@/components/ui/command';

const commandGroups = [
  {
    heading: 'Actions',
    items: [
      {
        icon: <Calendar />,
        label: 'Calendar',
        shortcut: '⌘C',
        onSelect: () => console.log('Calendar selected'),
      },
      {
        icon: <Settings />,
        label: 'Settings',
        disabled: true,
        onSelect: () => console.log('Settings selected'),
      },
    ],
  },
];

<SimpleCommand groups={commandGroups} placeholder="Search commands..." emptyMessage="No commands found." />;
```

### With Icons

<ComponentPreview
  name="command-with-icons-demo"
  description="Command items rendered with leading icons for quick visual scanning."
/>

### With Footer

<ComponentPreview
  name="command-with-footer-demo"
  description="Command palette with a persistent footer hint bar showing navigation shortcuts."
/>

### Loading State

<ComponentPreview
  name="command-loading-demo"
  description="Command palette with loading indicator while async results are fetched."
/>

### Result Breadcrumbs

<ComponentPreview
  name="command-result-breadcrumbs-demo"
  description="Command result rows rendered with a breadcrumb context path (cluster > topic > partition)."
/>

### Dialog

<ComponentPreview name="command-dialog-demo" description="A command menu in a dialog" />

To show the command menu in a dialog, use the `<CommandDialog />` component.

`CommandDialog` accepts a `showCloseButton` prop that is forwarded to the underlying `DialogContent`. It defaults to `true` (a close button is rendered), which differs from shadcn/ui where it defaults to `false`. Pass `showCloseButton={false}` to hide the close button.

```tsx
export function CommandMenu() {
  const [open, setOpen] = React.useState(false);
  const invokingControl = React.useRef<HTMLElement | null>(null);

  React.useEffect(
    function bindPaletteShortcut() {
      const down = (e: KeyboardEvent) => {
        if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
          e.preventDefault();
          if (!open) {
            const activeControl = document.activeElement;
            invokingControl.current = activeControl instanceof HTMLElement ? activeControl : null;
          }
          setOpen((isOpen) => !isOpen);
        }
      };
      document.addEventListener('keydown', down);
      return () => document.removeEventListener('keydown', down);
    },
    [open],
  );

  return (
    <CommandDialog finalFocus={invokingControl} open={open} onOpenChange={setOpen}>
      <CommandInput placeholder="Type a command or search..." />
      <CommandList>
        <CommandEmpty>No results found.</CommandEmpty>
        <CommandGroup heading="Suggestions">
          <CommandItem>Calendar</CommandItem>
          <CommandItem>Search Emoji</CommandItem>
          <CommandItem>Calculator</CommandItem>
        </CommandGroup>
      </CommandList>
    </CommandDialog>
  );
}
```

For a triggerless keyboard shortcut, capture the focused control before opening and pass its ref as
`finalFocus`, as above. `CommandDialog` forwards this public focus destination to the underlying
dialog popup; closing returns focus to that control.

Pass props for the inner `Command` through `commandProps`, such as a custom `filter` when cmdk's
default scoring ranks the wrong entry first. Its `className` merges with the owned dialog recipe. `CommandDialog` always uses `variant="dialog"`; the contradictory `commandProps.variant` override is removed. Keep `size`, `filter`, `loop`, `shouldFilter`, and other inner command props as needed.

```tsx
<CommandDialog commandProps={{ filter: rankExactMatchesFirst }} onOpenChange={setOpen} open={open}>
  {/* ... */}
</CommandDialog>
```

### Submenu

Use `CommandSub`, `CommandSubTrigger`, and `CommandSubContent` to create nested command menus that open as a popover to the right of the trigger item.

<ComponentPreview name="command-submenu-demo" />

```tsx
function CommandWithSubmenu() {
  const [labelOpen, setLabelOpen] = React.useState(false);

  return (
    <Command>
      <CommandInput placeholder="Type a command or search..." />
      <CommandList>
        <CommandGroup heading="Actions">
          <CommandItem>Search</CommandItem>
          <CommandSub open={labelOpen} onOpenChange={setLabelOpen}>
            <CommandSubTrigger>Apply Label</CommandSubTrigger>
            <CommandSubContent>
              <Command>
                <CommandInput placeholder="Filter labels..." />
                <CommandList>
                  <CommandEmpty>No labels found.</CommandEmpty>
                  <CommandGroup>
                    <CommandItem>Bug</CommandItem>
                    <CommandItem>Feature</CommandItem>
                    <CommandItem>Enhancement</CommandItem>
                  </CommandGroup>
                </CommandList>
              </Command>
            </CommandSubContent>
          </CommandSub>
        </CommandGroup>
      </CommandList>
    </Command>
  );
}
```

#### Submenu Props

**`CommandSub`** - Root wrapper that manages submenu state with a Popover.

| Prop           | Type                      | Description                             |
| -------------- | ------------------------- | --------------------------------------- |
| `open`         | `boolean`                 | Whether the submenu is open             |
| `onOpenChange` | `(open: boolean) => void` | Callback when open state changes        |
| `children`     | `ReactNode`               | CommandSubTrigger and CommandSubContent |

**`CommandSubTrigger`** - Item that opens the submenu when selected. Renders a chevron icon on the right.

| Prop        | Type       | Default | Description                          |
| ----------- | ---------- | ------- | ------------------------------------ |
| `inset`     | `boolean?` | `false` | Indent the trigger with left padding |
| `className` | `string?`  | —       | Additional CSS classes               |

Inherits all props from `CommandItem`.

**`CommandSubContent`** - Popover content for the nested command list. Opens to the right of the trigger.

| Prop        | Type        | Description                     |
| ----------- | ----------- | ------------------------------- |
| `className` | `string?`   | Additional CSS classes          |
| `children`  | `ReactNode` | Nested Command with CommandList |

### Combobox

You can use the `<Command />` component as a combobox. See the [Combobox](/docs/combobox) page for more information.

## Props

<div className="flex flex-row gap-x-3">
  <ExternalLink href="https://cmdk.paco.me/" text="Docs" />
  <ExternalLink href="https://github.com/pacocoursey/cmdk" text="API Reference" />
</div>

## Credits

- We use [cmdk](https://cmdk.paco.me) for the command component.
- We take our inspiration from [Shadcn UI](https://ui.shadcn.com/docs/components/command) for the command style.
