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 134 apps in this directory
Formbricks
Analytics · Design Tools · Forms Surveys
Open-source experience management platform for in-app, website, email, and link surveys — privacy-first and fully self-hostable.
Formizee
Forms Surveys
An open-source form backend and builder platform — design forms, collect submissions, and get analytics without hosting your own server, positioned as an alternative to Formspree and Typeform.
fountain-ink
Blogging
A self-hostable, decentralized blogging platform built on Lens Protocol — own your content, audience, and distribution forever.
Ghost
Blogging · CMS
Open source headless Node.js CMS for professional publishing, paid memberships, and newsletters with a fully owned audience.
Hatchet
AI Development · Automation · Developer Tools
A Postgres-backed orchestration engine for background tasks, AI agents, and durable workflows that replaces Redis queues and multi-datastore durable execution platforms with a single self-hostable service.
Helicone
AI Development · Analytics · Monitoring
An open-source AI gateway and LLM observability platform that routes requests to 100+ models while logging cost, latency, and full traces for every call.
HeyForm
Forms Surveys · No Code Platforms
Open-source conversational form builder with AI generation, conditional logic, and 30+ integrations — self-host with full data ownership.
GraphQL Hive
Developer Tools · Devops · Monitoring
Open-source GraphQL schema registry and observability platform with breaking change detection, federation support, and CI/CD integration for teams of any size.
hoop
Monitoring · Security
A wire-protocol gateway that enforces data masking, command blocking, approval workflows, and full session recording for engineers and AI agents accessing production infrastructure.