modern-cmdk 1.3.0 → 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,11 +9,7 @@
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://github.com/ABCrimson/modern-cmdk/blob/main/package.json"><img alt="core size budget" src="https://img.shields.io/badge/core-%3C%206.5%20kB%20gzip-dc2626?style=flat-square&labelColor=0a0e27"/></a>
13
- <a href="https://github.com/ABCrimson/modern-cmdk/blob/main/package.json"><img alt="react size budget" src="https://img.shields.io/badge/react-%3C%2012%20kB%20gzip-dc2626?style=flat-square&labelColor=0a0e27"/></a>
14
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>
15
- <a href="https://www.typescriptlang.org/"><img alt="TypeScript" src="https://img.shields.io/badge/TypeScript-7-dc2626?style=flat-square&labelColor=0a0e27"/></a>
16
- <a href="https://react.dev/"><img alt="React" src="https://img.shields.io/badge/React-19-dc2626?style=flat-square&labelColor=0a0e27"/></a>
17
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>
18
14
  </p>
19
15
 
@@ -26,32 +22,42 @@
26
22
 
27
23
  ---
28
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
+
29
27
  ## Install
30
28
 
31
29
  ```bash
32
30
  npm install modern-cmdk
33
31
  ```
34
32
 
35
- > [!NOTE]
36
- > `modern-cmdk` is ESM-only and declares `engines.node >= 26.4.0`. The optional WASM search
37
- > engine (`modern-cmdk-search-wasm`) is a private, unpublished workspace package (0.9.0) that you
38
- > build from source; it is not on npm.
39
-
40
- The package exports three entry points:
33
+ The package exports four entry points:
41
34
 
42
35
  ```ts
43
- import { createCommandMachine } from 'modern-cmdk'; // Core engine (no React)
44
- import { Command } from 'modern-cmdk/react'; // React 19 components
45
- 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
46
40
  ```
47
41
 
48
- React is an **optional** peer dependency — use the core engine standalone in any framework, or pair it with the React adapter. `modern-cmdk/react` imports `react`, `react-dom` and `radix-ui`, which are optional peers that npm and pnpm do not install for you, so add them yourself (the Quick Start below needs all three):
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:
43
+
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:
49
51
 
50
52
  ```bash
51
- npm install modern-cmdk react react-dom radix-ui
53
+ npm install modern-cmdk react react-dom
52
54
  ```
53
55
 
54
- ---
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.
55
61
 
56
62
  ## Quick Start
57
63
 
@@ -106,92 +112,17 @@ function CommandPalette() {
106
112
  }
107
113
  ```
108
114
 
109
- `<Command label="Command menu">` takes the same children inline, with no dialog; `<Command.Highlight text={...} ranges={...} />` renders match highlighting from scorer ranges.
110
-
111
- Or scaffold a new project:
112
-
113
- ```bash
114
- npm create modern-cmdk@latest my-palette -- --template=react-basic
115
- ```
116
-
117
- ---
118
-
119
- ## Why modern-cmdk?
120
-
121
- A ground-up rewrite of `cmdk` for **React 19** and **TypeScript 7**, written in modern ECMAScript. Framework-agnostic core. Zero compromise on performance, accessibility, or developer experience.
122
-
123
- | | cmdk | modern-cmdk |
124
- |---|---|---|
125
- | **Architecture** | React-only, tightly coupled | Framework-agnostic core + thin adapters |
126
- | **React** | 18 / 19 | 19 (`use()`, `useOptimistic`, `useId`, `ref` as prop) |
127
- | **Search** | Fuzzy (`command-score`) | Fuzzy scoring with match ranges; an experimental WASM engine (unpublished, does not work yet) |
128
- | **Ranking** | Static order | Frecency: frequency x bucketed recency weights |
129
- | **Virtualization** | None | Automatic variable-height, `content-visibility: auto` |
130
- | **Animations** | CSS transitions | GPU-composited: `@starting-style`, `scroll-timeline`, spring easing |
131
- | **Keyboard** | External | Built-in registry, `Mod` key, conflict detection |
132
- | **Accessibility** | Partial ARIA | Full WAI-ARIA combobox, `forced-colors`, `prefers-contrast` |
133
- | **Bundle** | not compared | Core ~6.4 kB, React ~9.8 kB gzip (budgets: < 6.5 kB, < 12 kB) |
134
- | **TypeScript** | 4.x/5.x | 7, isolated declarations, branded types |
135
- | **Cleanup** | Manual | `using`/`await using` (Explicit Resource Management) |
136
- | **Error handling** | None | `CommandErrorBoundary` with fallback UI |
137
- | **DevTools** | None | Built-in devtools hook for browser inspection |
138
-
139
- ---
140
-
141
- ## Features
142
-
143
- - **Framework-agnostic core** -- Pure TypeScript state machine. No React. No hard DOM dependency; DOM APIs are feature-detected and SSR-safe. Portable to any runtime. The sole runtime dependency (`idb-keyval`) is lazy-loaded only if you opt into IndexedDB frecency persistence.
144
- - **React 19 adapter** -- a `Command` root with 14 compound sub-components (`Command.Input` through `Command.Activity`). `useSyncExternalStore`, `useTransition`, `useOptimistic`, `use()` for Suspense. React Compiler compatible.
145
- - **Automatic virtualization** -- Variable-height virtual scrolling turns on when more than 100 items match and off again at 50 or fewer (fixed thresholds; force it with `<Command.List virtualize>`). Off-screen items use `content-visibility: auto`. The `virtualizeThreshold` option is accepted but not read yet.
146
- - **Fuzzy search** -- Built-in TypeScript scorer with incremental filtering. Experimental Rust/WASM engine _(private, not published to npm)_; it does not work yet and always falls back to the TS scorer.
147
- - **Frecency ranking** -- Frequency x recency, weighted by hour/day/week/month buckets. Pluggable persistence (memory or IndexedDB).
148
- - **Keyboard shortcuts** -- Built-in registry with cross-platform `Mod` key, and conflict detection. Cross-browser helper functions for grouping and set operations.
149
- - **Full accessibility** -- WAI-ARIA combobox pattern, `aria-live` announcements, `forced-colors`, `prefers-contrast`, `prefers-reduced-motion`.
150
- - **GPU-composited animations** -- `@starting-style` entry, `scroll-timeline` progress, spring `linear()` easing. All customizable via CSS custom properties.
151
- - **Error boundary** -- `CommandErrorBoundary` with static or render-function fallback.
152
- - **DevTools** -- `useCommandDevtools()` exposes machine state via `CustomEvent` for browser inspection.
153
- - **Telemetry middleware** -- Pluggable hooks for palette open/close, search, and item selection analytics.
154
- - **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.
155
-
156
- ---
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`.
157
116
 
158
- ## React Components
159
-
160
- ```tsx
161
- <Command> {/* Root -- state machine provider */}
162
- <Command.Input /> {/* Search input */}
163
- <Command.List> {/* Scrollable list with auto-virtualization */}
164
- <Command.Empty /> {/* Shown when filteredCount === 0 */}
165
- <Command.Loading /> {/* renders when the `loading` prop is true (or while the active-item transition is pending) */}
166
- <Command.Group> {/* Labeled group of items */}
167
- <Command.Item> {/* Selectable item */}
168
- <Command.Highlight text={label} ranges={ranges} /> {/* Fuzzy match highlighting */}
169
- <Command.Badge /> {/* Status badge */}
170
- <Command.Shortcut /> {/* Keyboard shortcut display */}
171
- </Command.Item>
172
- </Command.Group>
173
- <Command.Separator />
174
- </Command.List>
175
- </Command>
176
-
177
- <Command.Dialog /> {/* Radix Dialog + overlay + portal */}
178
- <Command.Page /> {/* Nested page navigation */}
179
- <Command.AsyncItems /> {/* Suspense-powered async loading */}
180
- ```
181
-
182
- ---
183
-
184
- ## Core API (No React)
185
-
186
- Use the core engine standalone in any framework or runtime:
117
+ ## Core API (no React)
187
118
 
188
119
  ```ts
189
120
  import { createCommandMachine, itemId } from 'modern-cmdk';
190
121
 
191
122
  using machine = createCommandMachine({
192
123
  items: [
193
- { id: itemId('copy'), value: 'Copy', shortcut: 'Mod+C', onSelect: () => copy() },
194
- { 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)) },
195
126
  ],
196
127
  frecency: { enabled: true },
197
128
  loop: true,
@@ -207,56 +138,38 @@ machine.subscribe(() => {
207
138
  // Automatic cleanup via `using` -- no manual dispose needed
208
139
  ```
209
140
 
210
- ---
211
-
212
- ## Performance
213
-
214
- | Benchmark | Target | Measured (CI runner) |
215
- |---|---|---|
216
- | Search 10K items (TS scorer) | < 16 ms | ~3.5 ms median |
217
- | State update: `SEARCH_CHANGE` | < 4 ms | ~0.37 ms median |
218
- | State update: `NAVIGATE` | < 1 ms | ~0.00075 ms median |
219
- | Core bundle (gzipped) | <= 6.5 KB | ~6.4 KB |
220
- | React bundle (gzipped) | <= 12 KB | ~9.8 KB |
141
+ ## What is in it
221
142
 
222
- Timings are medians from `benchmarks/baseline.json`: one CI run of the standalone harness, three runs of 1,000 iterations averaged, measured on a shared GitHub Actions
223
- runner (noise is +/-20-40 %). CI compares new runs against that baseline with 5 % warning / 15 % failure
224
- thresholds as a coarse tripwire, not a precise regression gate; the `NAVIGATE` baseline sits below the 0.01 ms noise floor and is reported, not compared, and a median above its target fails. There is no published WASM benchmark.
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.
225
151
 
226
- ---
152
+ Theming (CSS custom properties, `@layer command`) is covered in the [theming guide](https://abcrimson.github.io/modern-cmdk/guide/theming.html).
227
153
 
228
- ## CSS Customization
229
-
230
- All animations and dimensions are customizable via CSS custom properties:
231
-
232
- ```css
233
- [data-command-root] {
234
- --command-duration-enter: 200ms;
235
- --command-duration-exit: 150ms;
236
- --command-scale-from: 0.96;
237
- --command-overlay-blur: 4px;
238
- --command-dialog-radius: 12px;
239
- --command-dialog-max-width: 640px;
240
- --command-item-height: 44px;
241
- --command-highlight-color: oklch(0.85 0.15 90 / 0.3);
242
- --command-muted-color: light-dark(oklch(0.45 0.015 260), oklch(0.75 0.015 260));
243
- }
244
- ```
154
+ ## Sizes
245
155
 
246
- `--command-muted-color` colours secondary text (group headings, shortcuts, the empty state, the
247
- placeholder). Its default uses `light-dark()`, which follows the used `color-scheme`: set
248
- `color-scheme` on `:root` or a parent (for example `color-scheme: dark` on a dark theme), or override
249
- `--command-muted-color`. A dark-themed page that sets no `color-scheme` gets the light value on its dark
250
- surface (about 2.4:1 contrast).
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.
251
157
 
252
- 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 |
253
167
 
254
- ---
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.
255
169
 
256
170
  ## Migration from cmdk
257
171
 
258
- Four codemods ship as the `modern-cmdk` bin. Pass a transform name and a glob (quote the glob so your
259
- shell does not expand it):
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):
260
173
 
261
174
  ```bash
262
175
  npx modern-cmdk --help
@@ -271,50 +184,37 @@ npx modern-cmdk import-rewrite "./src/**/*.tsx"
271
184
  | `forward-ref` | Removes `React.forwardRef` wrappers (React 19) |
272
185
  | `should-filter` | Converts the `shouldFilter` prop to `filter` |
273
186
 
274
- Options: `--dry-run` lists the files that would change and writes nothing; `--concurrency=N` sets how
275
- many files are processed at once (default 8); `--strict` is described below.
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.
276
188
 
277
- A run prints one `changed <file>` line per rewritten file and a summary. With `--dry-run` the lines read
278
- `would change <file>` and the summary ends in `(dry run, nothing written)`:
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)`:
279
190
 
280
191
  ```text
281
192
  would change src/a.tsx
282
193
  1 changed, 0 unchanged, 0 errors (dry run, nothing written)
283
194
  ```
284
195
 
285
- Exit codes in 1.x are unchanged by default: `0` for `--help`, missing arguments and per-file errors, and
286
- `1` for an unknown transform, a glob that matches no files, or an uncaught error. An unknown option is
287
- warned about on stderr and ignored when the transform and glob are present. A malformed known option
288
- (`--concurrency` with no value, `--dry-run=yes`) is a usage error that writes nothing and exits `0`.
289
- With `--strict`, every usage error (including an unknown option, an unknown transform and a malformed
290
- option) exits `2`, and any file error exits `1`.
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`.
291
197
 
292
198
  See the [full migration guide](https://abcrimson.github.io/modern-cmdk/guide/migration-from-cmdk.html).
293
199
 
294
- ---
295
-
296
200
  ## Documentation
297
201
 
298
- **[abcrimson.github.io/modern-cmdk](https://abcrimson.github.io/modern-cmdk/)**
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)
299
203
 
300
- **Guides:** [Getting Started](https://abcrimson.github.io/modern-cmdk/guide/getting-started.html) | [Installation](https://abcrimson.github.io/modern-cmdk/guide/installation.html) | [Basic Usage](https://abcrimson.github.io/modern-cmdk/guide/basic-usage.html) | [Async Items](https://abcrimson.github.io/modern-cmdk/guide/async-items.html) | [WASM Search](https://abcrimson.github.io/modern-cmdk/guide/wasm-search.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) | [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)
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)
301
205
 
302
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)
303
207
 
304
- **API:** [Core Engine](https://abcrimson.github.io/modern-cmdk/api/command.html) | [React Adapter](https://abcrimson.github.io/modern-cmdk/api/command-react.html) | [WASM Search](https://abcrimson.github.io/modern-cmdk/api/command-search-wasm.html)
305
-
306
- ---
208
+ ## Related packages
307
209
 
308
- ## Related Packages
309
-
310
- | Package | Description |
210
+ | Package | Status |
311
211
  |---|---|
312
- | [`create-modern-cmdk`](https://www.npmjs.com/package/create-modern-cmdk) | `npm create modern-cmdk@latest <name>` -- scaffold a new project |
313
- | `modern-cmdk-search-wasm` _(private 0.9.0, not published; build from source)_ | Experimental Rust/WASM fuzzy search |
314
- | `vscode-modern-cmdk` _(not yet published)_ | 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. |
315
215
 
316
- ---
216
+ The repository page, with development and contributing notes, is [github.com/ABCrimson/modern-cmdk](https://github.com/ABCrimson/modern-cmdk).
317
217
 
318
218
  ## License
319
219
 
320
- [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
@@ -7427,7 +7427,7 @@ const globby = normalizeArguments(async (patterns, options) => {
7427
7427
  return unionFastGlobResultsAsync(results, filter);
7428
7428
  });
7429
7429
  const { convertPathToPattern } = import_out.default;
7430
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/utils/intersection.js
7430
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/utils/intersection.js
7431
7431
  var require_intersection = /* @__PURE__ */ __commonJSMin(((exports, module) => {
7432
7432
  /**
7433
7433
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -21523,7 +21523,7 @@ var require_main = /* @__PURE__ */ __commonJSMin(((exports) => {
21523
21523
  });
21524
21524
  }
21525
21525
  }));
21526
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/utils/union.js
21526
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/utils/union.js
21527
21527
  var require_union = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21528
21528
  /**
21529
21529
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -21541,7 +21541,7 @@ var require_union = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21541
21541
  return Array.from(result);
21542
21542
  };
21543
21543
  }));
21544
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/Collection.js
21544
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/Collection.js
21545
21545
  /**
21546
21546
  * Copyright (c) Facebook, Inc. and its affiliates.
21547
21547
  *
@@ -21874,7 +21874,7 @@ var require_Collection = /* @__PURE__ */ __commonJSMin(((exports) => {
21874
21874
  exports.hasConflictingRegistration = hasConflictingRegistration;
21875
21875
  exports.setDefaultCollectionType = setDefaultCollectionType;
21876
21876
  }));
21877
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/matchNode.js
21877
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/matchNode.js
21878
21878
  /**
21879
21879
  * Copyright (c) Facebook, Inc. and its affiliates.
21880
21880
  *
@@ -21902,7 +21902,7 @@ var require_matchNode = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21902
21902
  }
21903
21903
  module.exports = matchNode;
21904
21904
  }));
21905
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/utils/once.js
21905
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/utils/once.js
21906
21906
  var require_once = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21907
21907
  /**
21908
21908
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -21923,7 +21923,7 @@ var require_once = /* @__PURE__ */ __commonJSMin(((exports, module) => {
21923
21923
  };
21924
21924
  };
21925
21925
  }));
21926
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/collections/Node.js
21926
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/collections/Node.js
21927
21927
  /**
21928
21928
  * Copyright (c) Facebook, Inc. and its affiliates.
21929
21929
  *
@@ -22071,7 +22071,7 @@ var require_Node = /* @__PURE__ */ __commonJSMin(((exports) => {
22071
22071
  }
22072
22072
  exports.register = once(register);
22073
22073
  }));
22074
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/collections/VariableDeclarator.js
22074
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/collections/VariableDeclarator.js
22075
22075
  /**
22076
22076
  * Copyright (c) Facebook, Inc. and its affiliates.
22077
22077
  *
@@ -22167,7 +22167,7 @@ renameTo: function(newName) {
22167
22167
  exports.register = once(register);
22168
22168
  exports.filters = filterMethods;
22169
22169
  }));
22170
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/collections/JSXElement.js
22170
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/collections/JSXElement.js
22171
22171
  /**
22172
22172
  * Copyright (c) Facebook, Inc. and its affiliates.
22173
22173
  *
@@ -22324,7 +22324,7 @@ getRootName: function(path) {
22324
22324
  exports.filters = filterMethods;
22325
22325
  exports.mappings = mappingMethods;
22326
22326
  }));
22327
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/collections/ImportDeclaration.js
22327
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/collections/ImportDeclaration.js
22328
22328
  /**
22329
22329
  * Copyright (c) Facebook, Inc. and its affiliates.
22330
22330
  *
@@ -22395,7 +22395,7 @@ var require_ImportDeclaration = /* @__PURE__ */ __commonJSMin(((exports) => {
22395
22395
  }
22396
22396
  exports.register = once(register);
22397
22397
  }));
22398
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/collections/index.js
22398
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/collections/index.js
22399
22399
  var require_collections = /* @__PURE__ */ __commonJSMin(((exports, module) => {
22400
22400
  /**
22401
22401
  * Copyright (c) Facebook, Inc. and its affiliates.
@@ -35145,7 +35145,7 @@ var require_lib = /* @__PURE__ */ __commonJSMin(((exports) => {
35145
35145
  exports.parseExpression = parseExpression;
35146
35146
  exports.tokTypes = tokTypes;
35147
35147
  }));
35148
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/parser/babylon.js
35148
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/parser/babylon.js
35149
35149
  /**
35150
35150
  * Copyright (c) Facebook, Inc. and its affiliates.
35151
35151
  *
@@ -43182,7 +43182,7 @@ var require_dist = /* @__PURE__ */ __commonJSMin(((exports) => {
43182
43182
  stripFlowTypes: StripFlowTypes.transformProgram
43183
43183
  };
43184
43184
  }));
43185
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/parser/flow.js
43185
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/parser/flow.js
43186
43186
  /**
43187
43187
  * Copyright (c) Facebook, Inc. and its affiliates.
43188
43188
  *
@@ -43211,7 +43211,7 @@ var require_flow = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43211
43211
  } };
43212
43212
  };
43213
43213
  }));
43214
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/parser/tsOptions.js
43214
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/parser/tsOptions.js
43215
43215
  /**
43216
43216
  * Copyright (c) Facebook, Inc. and its affiliates.
43217
43217
  *
@@ -43256,7 +43256,7 @@ var require_tsOptions = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43256
43256
  ]
43257
43257
  };
43258
43258
  }));
43259
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/parser/ts.js
43259
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/parser/ts.js
43260
43260
  /**
43261
43261
  * Copyright (c) Facebook, Inc. and its affiliates.
43262
43262
  *
@@ -43276,7 +43276,7 @@ var require_ts = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43276
43276
  } };
43277
43277
  };
43278
43278
  }));
43279
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/parser/tsx.js
43279
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/parser/tsx.js
43280
43280
  /**
43281
43281
  * Copyright (c) Facebook, Inc. and its affiliates.
43282
43282
  *
@@ -43298,7 +43298,7 @@ var require_tsx = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43298
43298
  } };
43299
43299
  };
43300
43300
  }));
43301
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/parser/babel5Compat.js
43301
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/parser/babel5Compat.js
43302
43302
  /**
43303
43303
  * Copyright (c) Facebook, Inc. and its affiliates.
43304
43304
  *
@@ -43341,7 +43341,7 @@ var require_babel5Compat = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43341
43341
  } };
43342
43342
  };
43343
43343
  }));
43344
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/getParser.js
43344
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/getParser.js
43345
43345
  /**
43346
43346
  * Copyright (c) Facebook, Inc. and its affiliates.
43347
43347
  *
@@ -43359,7 +43359,7 @@ var require_getParser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43359
43359
  }
43360
43360
  };
43361
43361
  }));
43362
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/template.js
43362
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/template.js
43363
43363
  /**
43364
43364
  * Copyright (c) Facebook, Inc. and its affiliates.
43365
43365
  *
@@ -43450,7 +43450,7 @@ var require_template = /* @__PURE__ */ __commonJSMin(((exports, module) => {
43450
43450
  };
43451
43451
  };
43452
43452
  }));
43453
- // ../../node_modules/.pnpm/jscodeshift@17.4.0/node_modules/jscodeshift/src/core.js
43453
+ // ../../node_modules/.pnpm/jscodeshift@17.4.0_supports-color@7.2.0/node_modules/jscodeshift/src/core.js
43454
43454
  /**
43455
43455
  * Copyright (c) Facebook, Inc. and its affiliates.
43456
43456
  *
@@ -43623,6 +43623,8 @@ function usageText(stream) {
43623
43623
  ` ${opt("--strict")}Exit 2 on usage errors (incl. unknown options), 1 on file errors`,
43624
43624
  ` ${opt("--concurrency=N")}Files processed at once (default 8)`,
43625
43625
  ` ${opt("-h, --help")}Show this help`,
43626
+ "",
43627
+ "Node >= 26.4.0 (the floor modern-cmdk's toolchain and create-modern-cmdk declare; modern-cmdk itself declares no engines)",
43626
43628
  ""
43627
43629
  ].join("\n");
43628
43630
  }