modern-cmdk 1.2.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Crimson Dev
3
+ Copyright (c) 2026 Albert Badalov
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -9,43 +9,55 @@
9
9
 
10
10
  <p align="center">
11
11
  <a href="https://www.npmjs.com/package/modern-cmdk"><img alt="npm version" src="https://img.shields.io/npm/v/modern-cmdk?style=flat-square&color=dc2626&labelColor=0a0e27"/></a>
12
- <a href="https://bundlephobia.com/package/modern-cmdk"><img alt="bundle size" src="https://img.shields.io/bundlephobia/minzip/modern-cmdk?style=flat-square&color=dc2626&labelColor=0a0e27&label=core"/></a>
13
12
  <a href="https://github.com/ABCrimson/modern-cmdk/actions/workflows/ci.yml"><img alt="CI" src="https://img.shields.io/github/actions/workflow/status/ABCrimson/modern-cmdk/ci.yml?style=flat-square&color=dc2626&labelColor=0a0e27&label=CI"/></a>
14
- <a href="https://www.typescriptlang.org/"><img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-7.0-dc2626?style=flat-square&labelColor=0a0e27"/></a>
15
- <a href="https://react.dev/"><img alt="React" src="https://img.shields.io/badge/React-19-dc2626?style=flat-square&labelColor=0a0e27"/></a>
16
13
  <a href="https://github.com/ABCrimson/modern-cmdk/blob/main/LICENSE"><img alt="MIT License" src="https://img.shields.io/npm/l/modern-cmdk?style=flat-square&color=dc2626&labelColor=0a0e27"/></a>
17
14
  </p>
18
15
 
19
16
  <p align="center">
20
- <a href="https://command.crimson.dev">Documentation</a> &middot;
21
- <a href="https://command.crimson.dev/guide/getting-started">Getting Started</a> &middot;
22
- <a href="https://command.crimson.dev/api/command">API Reference</a> &middot;
23
- <a href="https://command.crimson.dev/examples/basic">Examples</a>
17
+ <a href="https://abcrimson.github.io/modern-cmdk/">Documentation</a> &middot;
18
+ <a href="https://abcrimson.github.io/modern-cmdk/guide/getting-started.html">Getting Started</a> &middot;
19
+ <a href="https://abcrimson.github.io/modern-cmdk/api/command.html">API Reference</a> &middot;
20
+ <a href="https://abcrimson.github.io/modern-cmdk/examples/basic.html">Examples</a>
24
21
  </p>
25
22
 
26
23
  ---
27
24
 
25
+ A ground-up rewrite of `cmdk` for **React 19**, written in modern ECMAScript: a framework-agnostic state machine (search, frecency ranking, keyboard shortcuts) in the core, and a thin React adapter on top.
26
+
28
27
  ## Install
29
28
 
30
29
  ```bash
31
30
  npm install modern-cmdk
32
31
  ```
33
32
 
34
- > [!NOTE]
35
- > `modern-cmdk` is ESM-only and declares `engines.node >= 26.4.0`. The optional WASM search
36
- > engine (`modern-cmdk-search-wasm`) is experimental and not yet published to npm.
37
-
38
- The package exports three entry points:
33
+ The package exports four entry points:
39
34
 
40
35
  ```ts
41
- import { createCommandMachine } from 'modern-cmdk'; // Core engine (no React)
42
- import { Command } from 'modern-cmdk/react'; // React 19 components
43
- import 'modern-cmdk/styles.css'; // Default styles
36
+ import { createCommandMachine } from 'modern-cmdk'; // Core engine (no React)
37
+ import { Command } from 'modern-cmdk/react'; // React components
38
+ import { CommandDialog } from 'modern-cmdk/react/dialog'; // CommandDialog alone
39
+ import 'modern-cmdk/styles.css'; // Default styles
44
40
  ```
45
41
 
46
- React is an **optional** peer dependency — use the core engine standalone in any framework, or pair it with the React adapter for a batteries-included experience.
42
+ `modern-cmdk` is ESM-only. The core entry imports no peer. Every import of `modern-cmdk/react` and of `modern-cmdk/react/dialog` loads `react`, `react-dom` and `radix-ui` (the `radix-ui` import is static), so these are the peers:
47
43
 
48
- ---
44
+ | Peer | Range | Status |
45
+ |---|---|---|
46
+ | `react` | `>=19.0.0 <21.0.0` | optional (only the React entries use it) |
47
+ | `react-dom` | `>=19.0.0 <21.0.0` | optional (only the React entries use it) |
48
+ | `radix-ui` | `>=1.4.0 <2.0.0` | required through 1.x |
49
+
50
+ `radix-ui` is a required peer of `modern-cmdk` in 1.x, so npm 7+ and pnpm install it with `modern-cmdk` (or warn when they cannot), and with it its own required peers `react` and `react-dom`, even when you use only the core; `modern-cmdk` itself marks only `react` and `react-dom` optional. It becomes optional again in 2.0, when the barrel drops `Command.Dialog` and only `modern-cmdk/react/dialog` needs it. For the React entries, add the React peers yourself:
51
+
52
+ ```bash
53
+ npm install modern-cmdk react react-dom
54
+ ```
55
+
56
+ `Command.Dialog` stays on the `modern-cmdk/react` barrel through 1.x and leaves it in 2.0; `modern-cmdk/react/dialog` exports `CommandDialog` alone.
57
+
58
+ The codemod bin and `create-modern-cmdk` are supported on Node >=26.4.0 (`create-modern-cmdk` declares it in `engines`; the codemod no longer does, from 1.4.0). `modern-cmdk` itself declares no `engines`.
59
+
60
+ `sideEffects` lists only `./dist/react/styles.css`; every JavaScript entry is side-effect-free for bundlers.
49
61
 
50
62
  ## Quick Start
51
63
 
@@ -54,122 +66,63 @@ React is an **optional** peer dependency — use the core engine standalone in a
54
66
 
55
67
  import { Command } from 'modern-cmdk/react';
56
68
  import 'modern-cmdk/styles.css';
69
+ import { useEffect, useState } from 'react';
57
70
 
58
71
  function CommandPalette() {
72
+ const [open, setOpen] = useState(false);
73
+
74
+ // Nothing opens the dialog for you: toggle it from a Mod+K listener (Cmd+K / Ctrl+K).
75
+ useEffect(() => {
76
+ const onKeyDown = (e: KeyboardEvent) => {
77
+ if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {
78
+ e.preventDefault();
79
+ setOpen((o) => !o);
80
+ }
81
+ };
82
+ document.addEventListener('keydown', onKeyDown);
83
+ return () => document.removeEventListener('keydown', onKeyDown);
84
+ }, []);
85
+
59
86
  return (
60
- <Command.Dialog>
87
+ <Command.Dialog open={open} onOpenChange={setOpen} label="Command Menu">
61
88
  <Command.Input placeholder="Type a command..." />
62
89
  <Command.List>
63
90
  <Command.Empty>No results found.</Command.Empty>
64
91
 
65
92
  <Command.Group heading="Actions">
66
- <Command.Item value="copy" onSelect={() => copyToClipboard()}>
67
- <Command.Highlight>Copy to Clipboard</Command.Highlight>
68
- <Command.Shortcut>Mod+C</Command.Shortcut>
93
+ <Command.Item value="copy" onSelect={() => setOpen(false)}>
94
+ Copy to Clipboard
95
+ <Command.Shortcut shortcut="Mod+C" />
69
96
  </Command.Item>
70
- <Command.Item value="paste" onSelect={() => paste()}>
71
- <Command.Highlight>Paste</Command.Highlight>
72
- <Command.Shortcut>Mod+V</Command.Shortcut>
97
+ <Command.Item value="paste" onSelect={() => setOpen(false)}>
98
+ Paste
99
+ <Command.Shortcut shortcut="Mod+V" />
73
100
  </Command.Item>
74
101
  </Command.Group>
75
102
 
76
103
  <Command.Group heading="Navigation">
77
- <Command.Item value="settings" onSelect={() => navigate('/settings')}>
104
+ <Command.Item value="settings" onSelect={() => setOpen(false)}>
78
105
  Settings
79
106
  <Command.Badge>New</Command.Badge>
80
107
  </Command.Item>
81
108
  </Command.Group>
82
109
  </Command.List>
83
- <Command.Loading>Searching...</Command.Loading>
84
110
  </Command.Dialog>
85
111
  );
86
112
  }
87
113
  ```
88
114
 
89
- Or scaffold a new project instantly:
90
-
91
- ```bash
92
- npm create modern-cmdk
93
- ```
94
-
95
- ---
96
-
97
- ## Why modern-cmdk?
98
-
99
- A ground-up rewrite of `cmdk` for **React 19**, **ES2026**, and **TypeScript 7**. Framework-agnostic core. Zero compromise on performance, accessibility, or developer experience.
100
-
101
- | | cmdk | modern-cmdk |
102
- |---|---|---|
103
- | **Architecture** | React-only, tightly coupled | Framework-agnostic core + thin adapters |
104
- | **React** | 18 | 19 (`use()`, `useOptimistic`, `useId`, `ref` as prop) |
105
- | **Search** | Basic substring | Fuzzy scoring + optional WASM (sub-1ms on 100K items) |
106
- | **Ranking** | Static order | Frecency with time-based exponential decay |
107
- | **Virtualization** | None | Automatic variable-height, `content-visibility: auto` |
108
- | **Animations** | CSS transitions | GPU-composited: `@starting-style`, `scroll-timeline`, spring easing |
109
- | **Keyboard** | External | Built-in registry, `Mod` key, conflict detection |
110
- | **Accessibility** | Partial ARIA | Full WAI-ARIA combobox, `forced-colors`, `prefers-contrast` |
111
- | **Bundle** | ~6 KB | Core ~6.4 KB, React ~9.8 KB |
112
- | **TypeScript** | 4.x/5.x | 7.0, isolated declarations, branded types |
113
- | **Cleanup** | Manual | `using`/`await using` (Explicit Resource Management) |
114
- | **Error handling** | None | `CommandErrorBoundary` with fallback UI |
115
- | **DevTools** | None | Built-in devtools hook for browser inspection |
116
-
117
- ---
118
-
119
- ## Features
120
-
121
- - **Framework-agnostic core** -- Pure TypeScript state machine. No DOM. No React. Portable to any runtime. The sole runtime dependency (`idb-keyval`) is lazy-loaded only if you opt into IndexedDB frecency persistence.
122
- - **React 19 adapter** -- 14 compound components. `useSyncExternalStore`, `useTransition`, `useOptimistic`, `use()` for Suspense. React Compiler compatible.
123
- - **Automatic virtualization** -- Variable-height virtual scrolling kicks in at a configurable threshold (`virtualizeThreshold`, default 100). Handles 100K+ items smoothly with `content-visibility: auto`.
124
- - **Fuzzy search** -- Built-in TypeScript scorer with incremental filtering. Optional Rust/WASM engine for sub-1ms on 100K items with graceful TS fallback _(experimental, not yet published to npm)_.
125
- - **Frecency ranking** -- Frequency x recency with time-based exponential decay. Pluggable persistence (memory or IndexedDB).
126
- - **Keyboard shortcuts** -- Built-in registry with cross-platform `Mod` key, conflict detection, and `RegExp.escape` parsing. Cross-browser helper functions for grouping and set operations.
127
- - **Full accessibility** -- WAI-ARIA combobox pattern, `aria-live` announcements, `forced-colors`, `prefers-contrast`, `prefers-reduced-motion`.
128
- - **GPU-composited animations** -- `@starting-style` entry, `scroll-timeline` progress, spring `linear()` easing. All customizable via CSS custom properties.
129
- - **Error boundary** -- `CommandErrorBoundary` with static or render-function fallback.
130
- - **DevTools** -- `useCommandDevtools()` exposes machine state via `CustomEvent` for browser inspection.
131
- - **Telemetry middleware** -- Pluggable hooks for palette open/close, search, and item selection analytics.
132
- - **ESM-only** -- Zero CommonJS. Tree-shakeable -- the framework-agnostic core is side-effect-free; only the React entry and `styles.css` are flagged in `sideEffects`. Isolated declarations.
133
-
134
- ---
135
-
136
- ## React Components
137
-
138
- ```tsx
139
- <Command> {/* Root -- state machine provider */}
140
- <Command.Input /> {/* Search input */}
141
- <Command.List> {/* Scrollable list with auto-virtualization */}
142
- <Command.Empty /> {/* Shown when filteredCount === 0 */}
143
- <Command.Loading /> {/* Shown when loading */}
144
- <Command.Group> {/* Labeled group of items */}
145
- <Command.Item> {/* Selectable item */}
146
- <Command.Highlight /> {/* Fuzzy match highlighting */}
147
- <Command.Badge /> {/* Status badge */}
148
- <Command.Shortcut /> {/* Keyboard shortcut display */}
149
- </Command.Item>
150
- </Command.Group>
151
- <Command.Separator />
152
- </Command.List>
153
- </Command>
154
-
155
- <Command.Dialog /> {/* Radix Dialog + overlay + portal */}
156
- <Command.Page /> {/* Nested page navigation */}
157
- <Command.AsyncItems /> {/* Suspense-powered async loading */}
158
- ```
159
-
160
- ---
161
-
162
- ## Core API (No React)
115
+ `<Command label="Command menu">` takes the same children inline, with no dialog; `<Command.Highlight text={...} ranges={...} />` renders match highlighting from scorer ranges. To scaffold a project instead: `npm create modern-cmdk@latest my-palette -- --template=react-basic`.
163
116
 
164
- Use the core engine standalone in any framework or runtime:
117
+ ## Core API (no React)
165
118
 
166
119
  ```ts
167
120
  import { createCommandMachine, itemId } from 'modern-cmdk';
168
121
 
169
122
  using machine = createCommandMachine({
170
123
  items: [
171
- { id: itemId('copy'), value: 'Copy', shortcut: 'Mod+C', onSelect: () => copy() },
172
- { id: itemId('paste'), value: 'Paste', shortcut: 'Mod+V', onSelect: () => paste() },
124
+ { id: itemId('copy'), value: 'Copy', shortcut: 'Mod+C', onSelect: () => navigator.clipboard.writeText(getSelection()?.toString() ?? '') },
125
+ { id: itemId('paste'), value: 'Paste', shortcut: 'Mod+V', onSelect: () => navigator.clipboard.readText().then((text) => console.log('Pasted:', text)) },
173
126
  ],
174
127
  frecency: { enabled: true },
175
128
  loop: true,
@@ -185,81 +138,83 @@ machine.subscribe(() => {
185
138
  // Automatic cleanup via `using` -- no manual dispose needed
186
139
  ```
187
140
 
188
- ---
189
-
190
- ## Performance
191
-
192
- | Benchmark | Target | Measured |
193
- |---|---|---|
194
- | Search 10K items (TS scorer) | < 16 ms | ~8.2 ms |
195
- | Search 100K items (WASM) | < 1 ms | ~0.7 ms |
196
- | Filter 10K (incremental) | < 2 ms | ~1.1 ms |
197
- | State update cycle | < 4 ms | ~2.3 ms |
198
- | Core bundle (gzipped) | <= 6.5 KB | ~6.4 KB |
199
- | React bundle (gzipped) | <= 12 KB | ~9.8 KB |
200
-
201
- CI enforces 5% warning / 15% failure regression thresholds with 3-run averaging.
141
+ ## What is in it
202
142
 
203
- ---
143
+ - **Framework-agnostic core** -- a pure TypeScript state machine; DOM APIs are feature-detected and SSR-safe. The sole runtime dependency (`idb-keyval`) is lazy-loaded only if you opt into IndexedDB frecency persistence.
144
+ - **React 19 adapter** -- compound components over `useSyncExternalStore`, `useTransition` and `use()`; React Compiler compatible.
145
+ - **Automatic virtualization** -- turns on when more than 100 items match and off again at 50 or fewer (fixed thresholds; force it with `<Command.List virtualize>` or `virtualize={false}`). The `virtualizeThreshold` option is accepted but not read yet.
146
+ - **Fuzzy search and frecency** -- a built-in TypeScript scorer with match ranges, and frequency x recency ranking with memory or IndexedDB persistence. `modern-cmdk-search-wasm` is an experimental, unpublished workspace package that does not work yet.
147
+ - **Keyboard shortcuts** -- a registry with a cross-platform `Mod` key and conflict detection.
148
+ - **Accessibility** -- WAI-ARIA combobox pattern, `aria-live` announcements, `forced-colors`, `prefers-contrast`, `prefers-reduced-motion`.
149
+ - **Animation** -- the stylesheet defines the dialog enter and exit on opacity, scale and translate, which are compositor-only; the overlay fades opacity and also transitions `--command-overlay-opacity`, its background alpha, which repaints, and the list height and item background-color transitions are not compositor-only either. In 1.x neither the dialog nor the overlay animates on enter or exit, because their duration and easing tokens are declared only on `[data-command-root]`, which sits inside the dialog (DT-19, planned for 1.8.0).
150
+ - **Extras** -- `CommandErrorBoundary`, `useCommandDevtools()` and telemetry middleware.
204
151
 
205
- ## CSS Customization
152
+ Theming (CSS custom properties, `@layer command`) is covered in the [theming guide](https://abcrimson.github.io/modern-cmdk/guide/theming.html).
206
153
 
207
- All animations and dimensions are customizable via CSS custom properties:
154
+ ## Sizes
208
155
 
209
- ```css
210
- [data-command-root] {
211
- --command-duration-enter: 200ms;
212
- --command-duration-exit: 150ms;
213
- --command-scale-from: 0.96;
214
- --command-overlay-blur: 4px;
215
- --command-dialog-radius: 12px;
216
- --command-dialog-max-width: 640px;
217
- --command-item-height: 44px;
218
- --command-highlight-color: oklch(0.85 0.15 90 / 0.3);
219
- }
220
- ```
156
+ Figures come from [`benchmarks/size-history/1.4.0.json`](https://github.com/ABCrimson/modern-cmdk/blob/5f1e01e/benchmarks/size-history/1.4.0.json) (committed in `5f1e01e`, measured at `07bfe79` with size-limit 14.3.0) and the `size-limit` entries in the root `package.json`. Method: size-limit, gzip, peers (`react`, `react-dom`, `radix-ui`) ignored; the codemod bin is raw installed size.
221
157
 
222
- All styles use `@layer command` for zero-specificity conflicts and CSS logical properties for full RTL support.
158
+ | Entry | Bytes | Method |
159
+ |---|---|---|
160
+ | `modern-cmdk` (core) | 6355 | gzip |
161
+ | `modern-cmdk/react`, adapter only | 5403 | gzip, `modern-cmdk` ignored |
162
+ | `modern-cmdk` + `modern-cmdk/react` | 9830 | gzip, core included |
163
+ | `modern-cmdk/react/dialog`, adapter only | 1425 | gzip, `modern-cmdk` ignored |
164
+ | `modern-cmdk/react`, `CommandSeparator` only | 4767 | gzip, `modern-cmdk` ignored; still contains `CommandDialog`, `CommandRoot` and the `radix-ui` import (tree-shaking of the barrel is a 2.0 item) |
165
+ | `modern-cmdk/styles.css` | 3959 | gzip |
166
+ | codemod bin (`dist/codemod/cli.mjs` plus `dist/codemod/transforms/*.mjs`) | 3325793 | raw installed size, not gzip |
223
167
 
224
- ---
168
+ 1.3's 9844 B React figure measured `dist/react/index.mjs` with the core inlined, so it was core plus adapter, not the adapter.
225
169
 
226
170
  ## Migration from cmdk
227
171
 
228
- Automated codemods handle the most common migration patterns:
172
+ Four codemods ship as the `modern-cmdk` bin, supported on Node >= 26.4.0. Pass a transform name and a glob (quote the glob so your shell does not expand it):
229
173
 
230
174
  ```bash
231
- npx modern-cmdk import-rewrite ./src
232
- npx modern-cmdk data-attrs ./src
233
- npx modern-cmdk forward-ref ./src
234
- npx modern-cmdk should-filter ./src
175
+ npx modern-cmdk --help
176
+ npx modern-cmdk import-rewrite "./src/**/*.tsx" --dry-run
177
+ npx modern-cmdk import-rewrite "./src/**/*.tsx"
235
178
  ```
236
179
 
237
- See the [full migration guide](https://command.crimson.dev/guide/migration-from-cmdk).
180
+ | Transform | What it does |
181
+ |---|---|
182
+ | `import-rewrite` | Rewrites `cmdk` imports to `modern-cmdk/react` |
183
+ | `data-attrs` | Converts `[cmdk-*]` selectors to `[data-command-*]` |
184
+ | `forward-ref` | Removes `React.forwardRef` wrappers (React 19) |
185
+ | `should-filter` | Converts the `shouldFilter` prop to `filter` |
238
186
 
239
- ---
187
+ Options: `--dry-run` lists the files that would change and writes nothing; `--concurrency=N` sets how many files are processed at once (default 8); `--strict` is described below.
240
188
 
241
- ## Documentation
189
+ A run prints one `changed <file>` line per rewritten file and a summary. With `--dry-run` the lines read `would change <file>` and the summary ends in `(dry run, nothing written)`:
242
190
 
243
- **[command.crimson.dev](https://command.crimson.dev)**
191
+ ```text
192
+ would change src/a.tsx
193
+ 1 changed, 0 unchanged, 0 errors (dry run, nothing written)
194
+ ```
244
195
 
245
- **Guides:** [Getting Started](https://command.crimson.dev/guide/getting-started) | [Installation](https://command.crimson.dev/guide/installation) | [Basic Usage](https://command.crimson.dev/guide/basic-usage) | [Async Items](https://command.crimson.dev/guide/async-items) | [WASM Search](https://command.crimson.dev/guide/wasm-search) | [Frecency](https://command.crimson.dev/guide/frecency) | [Shortcuts](https://command.crimson.dev/guide/shortcuts) | [Virtualization](https://command.crimson.dev/guide/virtualization) | [SSR / Next.js](https://command.crimson.dev/guide/ssr) | [Theming](https://command.crimson.dev/guide/theming) | [Accessibility](https://command.crimson.dev/guide/accessibility)
196
+ Exit codes in 1.x are unchanged by default: `0` for `--help`, missing arguments and per-file errors, and `1` for an unknown transform, a glob that matches no files, or an uncaught error. An unknown option is warned about on stderr and ignored when the transform and glob are present. A malformed known option (`--concurrency` with no value, `--dry-run=yes`) is a usage error that writes nothing and exits `0`. With `--strict`, every usage error (including an unknown option, an unknown transform and a malformed option) exits `2`, and any file error exits `1`.
246
197
 
247
- **Recipes:** [File Picker](https://command.crimson.dev/recipes/file-picker) | [Emoji Picker](https://command.crimson.dev/recipes/emoji-picker) | [AI Chat Commands](https://command.crimson.dev/recipes/ai-chat-commands) | [Nested Commands](https://command.crimson.dev/recipes/nested-commands) | [Spotlight Search](https://command.crimson.dev/recipes/spotlight-search)
198
+ See the [full migration guide](https://abcrimson.github.io/modern-cmdk/guide/migration-from-cmdk.html).
248
199
 
249
- **API:** [Core Engine](https://command.crimson.dev/api/command) | [React Adapter](https://command.crimson.dev/api/command-react) | [WASM Search](https://command.crimson.dev/api/command-search-wasm)
200
+ ## Documentation
250
201
 
251
- ---
202
+ **[abcrimson.github.io/modern-cmdk](https://abcrimson.github.io/modern-cmdk/)** -- [Installation](https://abcrimson.github.io/modern-cmdk/guide/installation.html) | [Basic Usage](https://abcrimson.github.io/modern-cmdk/guide/basic-usage.html) | [SSR / Next.js](https://abcrimson.github.io/modern-cmdk/guide/ssr.html) | [Theming](https://abcrimson.github.io/modern-cmdk/guide/theming.html) | [Accessibility](https://abcrimson.github.io/modern-cmdk/guide/accessibility.html) | [Core API](https://abcrimson.github.io/modern-cmdk/api/command.html) | [React API](https://abcrimson.github.io/modern-cmdk/api/command-react.html) | [Benchmarks](https://abcrimson.github.io/modern-cmdk/benchmarks.html)
252
203
 
253
- ## Related Packages
204
+ **More guides:** [Async Items](https://abcrimson.github.io/modern-cmdk/guide/async-items.html) | [Frecency](https://abcrimson.github.io/modern-cmdk/guide/frecency.html) | [Shortcuts](https://abcrimson.github.io/modern-cmdk/guide/shortcuts.html) | [Virtualization](https://abcrimson.github.io/modern-cmdk/guide/virtualization.html) | [TypeScript](https://abcrimson.github.io/modern-cmdk/guide/typescript-integration.html) | [Controlled Dialog](https://abcrimson.github.io/modern-cmdk/guide/controlled-dialog.html) | [WASM Search (experimental)](https://abcrimson.github.io/modern-cmdk/guide/wasm-search.html) | [WASM Search API (experimental)](https://abcrimson.github.io/modern-cmdk/api/command-search-wasm.html)
254
205
 
255
- | Package | Description |
206
+ **Recipes:** [File Picker](https://abcrimson.github.io/modern-cmdk/recipes/file-picker.html) | [Emoji Picker](https://abcrimson.github.io/modern-cmdk/recipes/emoji-picker.html) | [AI Chat Commands](https://abcrimson.github.io/modern-cmdk/recipes/ai-chat-commands.html) | [Nested Commands](https://abcrimson.github.io/modern-cmdk/recipes/nested-commands.html) | [Spotlight Search](https://abcrimson.github.io/modern-cmdk/recipes/spotlight-search.html)
207
+
208
+ ## Related packages
209
+
210
+ | Package | Status |
256
211
  |---|---|
257
- | [`create-modern-cmdk`](https://www.npmjs.com/package/create-modern-cmdk) | `npm create modern-cmdk` -- scaffold a new project |
258
- | `modern-cmdk-search-wasm` _(experimental, not yet published)_ | Rust/WASM fuzzy search -- sub-1ms on 100K items |
259
- | [`vscode-modern-cmdk`](https://marketplace.visualstudio.com/items?itemName=crimson-dev.vscode-modern-cmdk) | VS Code snippets extension |
212
+ | [`create-modern-cmdk`](https://www.npmjs.com/package/create-modern-cmdk) | Published. `npm create modern-cmdk@latest <name>` scaffolds a new project. |
213
+ | `modern-cmdk-search-wasm` | Experimental Rust/WASM fuzzy search; private (0.9.0), not on npm. |
214
+ | `vscode-modern-cmdk` | Not on the VS Code Marketplace. The npm 1.0.0 of that name was an accidental publish and is not the extension; the package is private from 1.4.0. |
260
215
 
261
- ---
216
+ The repository page, with development and contributing notes, is [github.com/ABCrimson/modern-cmdk](https://github.com/ABCrimson/modern-cmdk).
262
217
 
263
218
  ## License
264
219
 
265
- [MIT](https://github.com/ABCrimson/modern-cmdk/blob/main/LICENSE) -- Copyright (c) 2026 Crimson Dev
220
+ [MIT](https://github.com/ABCrimson/modern-cmdk/blob/main/LICENSE) -- Copyright (c) 2026 Albert Badalov