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
Polar
Developer Tools · Ecommerce · Invoicing Finance
Open source payments infrastructure that turns software into a business — subscriptions, usage-based billing, digital products, and merchant-of-record compliance in one platform.
rakazo
AI Agents · AI Assistants
An open-source platform for persistent AI teammates that own their own conversations, memory, routines, and computers — self-hosted, model-agnostic, and available on web, desktop, and mobile.
Rallly
Scheduling
Self-hostable group scheduling polls that eliminate back-and-forth emails and find the best meeting time for everyone.
Refly
AI Development · Automation · No Code Platforms
Build deterministic, versioned agent skills from natural language—run them anywhere from Claude Code to Slack.
Rivet
AI Agents · Developer Tools
Stateful actors as a primitive for AI agents, real-time collaboration, and durable execution — with in-memory state, WebSockets, queues, and scheduling built in.
rowboat
AI Assistants · AI Development
Build, test, and deploy multi-agent AI workflows with a visual editor, RAG data sources, MCP tool integration, and a production-ready REST API.
Rybbit
Analytics
Open-source, privacy-friendly web and product analytics with cookieless tracking, session replays, funnels, and real-time dashboards — a self-hostable alternative to Google Analytics.
Skyvern
AI Agents · Automation
Skyvern (YC S2023) automates browser-based workflows by pairing LLMs with computer vision, letting agents click, fill, and extract data on sites they've never seen, without brittle XPath selectors that break on every layout change.
Sourcebot
AI Code Assistants · Developer Tools · Search
A self-hosted, AI-powered code search engine that indexes every repo across GitHub, GitLab, Bitbucket, Gitea, Gerrit, and Azure DevOps, so both engineers and coding agents can search, browse, and ask questions about your codebase from one place.