cmdk
Fast, unstyled command menu and combobox primitives for React.
Repository Health
Technical Analysis
cmdk is a React component library for building command menus and comboboxes, including the “Cmd+K” pattern popularized by Linear, Vercel, and Raycast. It renders as an unstyled, fully composable set of primitives — Command, Input, List, Item, Group, and Dialog — that filter and sort items automatically as the user types, while leaving all visual styling to the consumer.
Built on top of Radix UI’s accessibility primitives (Dialog, Primitive, compose-refs, useId), cmdk keeps every item mounted in the React tree and toggles DOM visibility based on search state. This lets consumers use full component composition — wrapping items in other components, rendering async data, or building nested “pages” of items — rather than being constrained to a flat data array or render-prop API.
What You Get
- A
Commandroot plus composableInput,List,Item,Group,Separator,Empty, andLoadingprimitives - A
Command.Dialogvariant that wraps Radix UI’s Dialog/Portal for a Cmd+K style overlay out of the box - Built-in fuzzy filtering and sorting via an internal scoring algorithm, fully overridable with a custom
filterfunction or disabled withshouldFilter={false} - Full keyboard navigation (arrow keys, loop mode, escape-to-previous-page) and accessibility tested with VoiceOver and Chrome DevTools
- The
useCommandStatehook for subscribing to internal state, like the current search value, without re-rendering the whole menu
Common Use Cases
- Global Cmd+K command palettes for SaaS apps and dashboards (the pattern popularized by Linear, Vercel, and Raycast)
- Accessible search/filter comboboxes and autocomplete inputs
- Multi-step or nested command menus (e.g., ‘Change theme…’ drilling into ‘Dark’ / ‘Light’)
- Async, server-driven item lists (e.g., searching a live API) with automatic filtering as results stream in
Under The Hood
Architecture
The library is implemented as a single flat module (cmdk/src/index.tsx, ~1090 lines) plus a standalone fuzzy-matching helper (command-score.ts). It centers on a React context/store trio — CommandContext, StoreContext, and GroupContext — where a single external mutable Store (built with useLazyRef plus a listeners Set, effectively a hand-rolled useSyncExternalStore producer) holds search, value, selectedItemId, and a filtered map of item-to-score. Every Command.Item/Command.Group registers itself into allItems/allGroups/ids refs on mount via the item/group context callbacks, so DOM presence — not a backing array — is authoritative: items stay mounted in the React tree at all times and are hidden via re-render when filterItems() (invoked synchronously on every search state change) decides they don’t match. Keyboard navigation, scroll-into-view, and vim-style ctrl+n/j/p/k bindings are layered on top of this store through a schedule(id, fn) micro-scheduler that defers DOM-dependent work to the next layout-effect tick. The optional Command.Dialog wraps the whole tree in Radix UI’s Dialog/Portal, so the palette-in-a-modal use case reuses Radix’s focus-trap and escape/overlay handling rather than reimplementing it.
Tech Stack
The package is pure TypeScript compiled with tsup (ESM + CJS dual output, bundled .d.ts, minified, no sourcemaps per cmdk/tsup.config.ts) and has a minimal runtime dependency surface — four @radix-ui primitives (react-dialog, react-primitive, react-id, react-compose-refs) — with react/react-dom as peer dependencies supporting React 18 and 19 (including the 19 release-candidate range). The repository itself is a pnpm workspace (pnpm-workspace.yaml: cmdk, website, test) pinned to pnpm@8.8.0, with the publishable package isolated in cmdk/ and a Next.js 13 marketing/docs site (website/) and a Playwright test harness (test/) as separate private workspace members — a clean separation between the library and its surrounding tooling.
Code Quality
Tests live in test/*.test.ts (basic, dialog, group, item, keybind, numeric, props — 7 files) and run via Playwright against a live Next.js test page rather than a unit-test harness, so they exercise real DOM/keyboard behavior instead of mocking React internals — a deliberate choice given the library’s DOM-authoritative design. There’s no separate unit-test layer for command-score.ts’s scoring internals, so pure-function edge cases like transpositions and case penalties aren’t directly unit-tested. Source code is fully typed with exported prop types per primitive (ItemProps, GroupProps, DialogProps, etc.), consistent forwardRef usage, and JSDoc comments on nearly every public prop, which substitutes for prose documentation in the editor. Naming is consistent (useXxx hooks, Command.Xxx compound members), and the single-file architecture, while dense, is organized top-to-bottom by primitive.
API Design
The public API is a compound-component surface (Command, Command.Input, Command.List, Command.Item, Command.Group, Command.Separator, Command.Empty, Command.Loading, Command.Dialog) that mirrors Radix’s now-familiar pattern, so consumers already used to Radix primitives get a near-zero learning curve; getting a working filtered list requires only nesting the primitives, with no required data-array or render-prop wiring, and styling is entirely bring-your-own via [cmdk-*] data-attributes rather than shipped CSS. Escape hatches are well designed: filter/shouldFilter for custom or disabled matching, keywords for search aliases, forceMount to bypass filtering per item/group, and the useCommandState selector hook for advanced state reads without extra re-renders. The one piece of friction is the store’s loosely typed internal Context/Store (typed any in places like setState’s opts), which is invisible to consumers but signals the internal API prioritizes flexibility over strict typing.
Used by 133 apps in this directory
NoteGen
AI Assistants · Knowledge Management · Note Taking
Capture anything first, then let AI transform your scattered records into polished, structured Markdown notes with RAG-powered knowledge retrieval.
Novu
Developer Tools
Open-source communication infrastructure that connects your products and AI agents to every channel your users live on — Inbox, Email, SMS, Push, Chat, and more.
Onlook
AI Design Tools · Design Tools
An open-source, AI-first visual editor that lets designers and developers build, style, and deploy React apps directly in code — no handoff required.
open-agents
AI Agents · Developer Tools
Open-source reference app for building and running background AI coding agents on Vercel — from chat prompt to committed code changes without keeping your laptop involved.
OpenKnowledge
Code Editors · Knowledge Management · Note Taking
A beautiful, local-first markdown IDE that turns any git repo into a live collaborative workspace for humans and AI coding agents like Claude, Codex, and OpenCode.
open-notebook
AI Assistants · Note Taking
A privacy-first, self-hosted AI research notebook with 18+ model providers, multi-speaker podcast generation, and full REST API—your open-source alternative to Google Notebook LM.
Open Scouts
AI Agents · Automation
Create automated AI scouts that continuously search the web and send email alerts when they find what you're looking for.
OpenStatus
Devops · Monitoring
Open-source status pages and uptime monitoring with global synthetic checks, monitoring-as-code, and AI agent integration via MCP.
OpenCut
Design Tools · Social Media · Video Editors
Free, open-source video editor for web, desktop, and mobile — no watermarks, no subscriptions, built with a Rust core and plugin-first architecture