modern-cmdk 1.3.0 → 1.5.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
+ `modern-cmdk-codemod` and `create-modern-cmdk` support Node >=26.4.0 and declare it in `engines`; the deprecated `modern-cmdk` bin is supported on it too. `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.
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`.
155
116
 
156
- ---
157
-
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,114 +138,87 @@ machine.subscribe(() => {
207
138
  // Automatic cleanup via `using` -- no manual dispose needed
208
139
  ```
209
140
 
210
- ---
211
-
212
- ## Performance
141
+ ## What is in it
213
142
 
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 |
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.
221
151
 
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.
152
+ Theming (CSS custom properties, `@layer command`) is covered in the [theming guide](https://abcrimson.github.io/modern-cmdk/guide/theming.html).
225
153
 
226
- ---
154
+ ## Sizes
227
155
 
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
- ```
156
+ Figures come from [`benchmarks/size-history/1.5.0.json`](https://github.com/ABCrimson/modern-cmdk/blob/4498a0f/benchmarks/size-history/1.5.0.json) (committed in `4498a0f`, measured at `d5ce6ff` on 2026-11-07 with size-limit 14.3.0 and `npm pack --dry-run --json`). Method: size-limit, gzip, peers (`react`, `react-dom`, `radix-ui`) ignored; the codemod entries are raw installed size of the files named.
245
157
 
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).
158
+ | Entry | Bytes | Limit | Method |
159
+ |---|---|---|---|
160
+ | `modern-cmdk` (core) | 6399 | 6500 | gzip |
161
+ | `modern-cmdk/react`, adapter only | 5539 | 5600 | gzip, `modern-cmdk` ignored |
162
+ | `modern-cmdk` + `modern-cmdk/react` | 10003 | 10100 | gzip, core included |
163
+ | `modern-cmdk/react/dialog`, adapter only | 1422 | 1500 | gzip, `modern-cmdk` ignored |
164
+ | `modern-cmdk/react`, `CommandSeparator` only | 4812 | 5000 | 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 | 4000 | gzip |
166
+ | codemod bin (`dist/codemod/*.mjs` plus `dist/codemod/transforms/*.mjs`) | 3150372 | 3400000 | raw installed size, not gzip |
167
+ | codemod shim (`dist/codemod/bin.mjs`) | 897 | 1000 | raw installed size, not gzip |
251
168
 
252
- All styles use `@layer command` for zero-specificity conflicts and CSS logical properties for full RTL support.
253
-
254
- ---
169
+ The packed `modern-cmdk` tarball: 1.4 (built from `release/1.4.0` at `b77f133` and measured on 2026-11-05; not on npm) is 992157 B packed and 3473079 B unpacked in 16 entries, of which 147286 B is runtime and 3325793 B is the codemod; the 1.5 release candidate is 962822 B packed and 3315632 B unpacked in 22 entries, of which 165260 B is runtime (152384 B without `THIRD-PARTY-NOTICES.md`, which is 12876 B) and 3150372 B is the codemod, including the 897 B shim. The codemod's own package, `modern-cmdk-codemod`, is 33119 B packed and 113416 B unpacked in 11 entries; `jscodeshift` is not in that tarball.
255
170
 
256
171
  ## Migration from cmdk
257
172
 
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):
173
+ The codemods live in their own package, [`modern-cmdk-codemod`](https://github.com/ABCrimson/modern-cmdk/tree/main/packages/modern-cmdk-codemod) (Node >= 26.4.0; see its README for every option and exit code). Pass a transform name and a directory or a glob (quote the glob so your shell does not expand it). A real run needs a git work tree with the matched files committed, or `--force`; a dry run needs neither:
260
174
 
261
175
  ```bash
262
- npx modern-cmdk --help
263
- npx modern-cmdk import-rewrite "./src/**/*.tsx" --dry-run
264
- npx modern-cmdk import-rewrite "./src/**/*.tsx"
176
+ npx modern-cmdk-codemod --help
177
+ npx modern-cmdk-codemod --dry-run import-rewrite ./src
178
+ git status --short # empty: everything committed
179
+ npx modern-cmdk-codemod import-rewrite ./src
265
180
  ```
266
181
 
182
+ Run all four in this order, committing after each: `should-filter`, `forward-ref`, `data-attrs`, `import-rewrite`.
183
+
267
184
  | Transform | What it does |
268
185
  |---|---|
269
- | `import-rewrite` | Rewrites `cmdk` imports to `modern-cmdk/react` |
270
- | `data-attrs` | Converts `[cmdk-*]` selectors to `[data-command-*]` |
271
- | `forward-ref` | Removes `React.forwardRef` wrappers (React 19) |
272
- | `should-filter` | Converts the `shouldFilter` prop to `filter` |
186
+ | `import-rewrite` | Rewrites imports, re-exports, `import()`, `require()` and `vi.mock` or `jest.mock` of `'cmdk'` to `'modern-cmdk/react'`; reports the names and subpaths `modern-cmdk/react` lacks |
187
+ | `data-attrs` | Renames `cmdk-*` attributes to `data-command-*` and `--cmdk-list-height` to `--command-list-height` in JSX, in selectors inside JS/TS strings and in `.css` and `.scss` files; rewrites cmdk's state attributes beside them (`[data-selected="true"]` becomes `[data-active]`, `[data-disabled="true"]` becomes `[data-disabled]`) and the Tailwind variants on cmdk elements; reports what has no equivalent (`cmdk-label`, `cmdk-item-select`) or cannot be migrated automatically |
188
+ | `forward-ref` | Unwraps `forwardRef` from `react` into a function component that takes `ref` as a prop (React 19) |
189
+ | `should-filter` | Converts the `shouldFilter` prop to `filter` and wraps a cmdk `filter` function in an adapter to the `(item, query)` signature |
273
190
 
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.
191
+ Every site a transform cannot migrate is printed as `<path>: <message>` on stderr and left unchanged. Exit codes of `modern-cmdk-codemod`: `0` success (reports included), `1` a file errored or no file matched, `2` a usage error or a refused dirty tree.
276
192
 
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)`:
193
+ ### The deprecated `modern-cmdk` bin
279
194
 
280
- ```text
281
- would change src/a.tsx
282
- 1 changed, 0 unchanged, 0 errors (dry run, nothing written)
283
- ```
195
+ `modern-cmdk` still ships the old `modern-cmdk` bin until 2.0, as a shim (`dist/codemod/bin.mjs`) over the same four transforms. It is deprecated: it writes one deprecation warning to stderr per run and points to `modern-cmdk-codemod`. It keeps the 1.x behaviour: lenient exit codes unless argv carries `--strict` (without `--strict`, `0` for `--help`, missing arguments, usage errors and per-file errors; `1` for an unknown transform, no matching files and an uncaught error), 1.4's excludes (of the ten directories `modern-cmdk-codemod` skips, it skips only `node_modules`, `dist`, `build` and `.next`, and applies no `.gitignore`; like `modern-cmdk-codemod`, it reads only the ten script and stylesheet extensions from a directory, leaves out files and directories whose names start with a dot unless a pattern segment starts with that dot or a directory argument names that directory, descends no symlinked directory under `**` or a directory argument, reads no symlinked file and on Windows matches names case-insensitively; unlike it, it follows a symlinked directory that a pattern names or that a directory argument names, such as `"./src/link/*.tsx"` or `./src/link`), and no git check. The bin leaves in 2.0.
284
196
 
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`.
197
+ ### Third-party notices
291
198
 
292
- See the [full migration guide](https://abcrimson.github.io/modern-cmdk/guide/migration-from-cmdk.html).
199
+ The ten packages bundled into `dist/codemod` are listed with their licences in `THIRD-PARTY-NOTICES.md`, which ships in the `modern-cmdk` tarball. It is generated by `scripts/third-party-notices.ts` and checked by `pnpm check:notices`.
293
200
 
294
- ---
201
+ See the [full migration guide](https://abcrimson.github.io/modern-cmdk/guide/migration-from-cmdk.html).
295
202
 
296
203
  ## Documentation
297
204
 
298
- **[abcrimson.github.io/modern-cmdk](https://abcrimson.github.io/modern-cmdk/)**
205
+ **[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
206
 
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)
207
+ **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
208
 
302
209
  **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
210
 
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
- ---
211
+ ## Related packages
307
212
 
308
- ## Related Packages
309
-
310
- | Package | Description |
213
+ | Package | Status |
311
214
  |---|---|
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 |
215
+ | [`modern-cmdk-codemod`](https://github.com/ABCrimson/modern-cmdk/tree/main/packages/modern-cmdk-codemod) | The cmdk migration codemods as their own package from 1.5 (`npx modern-cmdk-codemod <transform> <dir or glob>`), strict by default. |
216
+ | [`create-modern-cmdk`](https://www.npmjs.com/package/create-modern-cmdk) | Published. `npm create modern-cmdk@latest <name>` scaffolds a new project. |
217
+ | `modern-cmdk-search-wasm` | Experimental Rust/WASM fuzzy search; private (0.9.0), not on npm. |
218
+ | `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
219
 
316
- ---
220
+ The repository page, with development and contributing notes, is [github.com/ABCrimson/modern-cmdk](https://github.com/ABCrimson/modern-cmdk).
317
221
 
318
222
  ## License
319
223
 
320
- [MIT](https://github.com/ABCrimson/modern-cmdk/blob/main/LICENSE) -- Copyright (c) 2026 Crimson Dev
224
+ [MIT](https://github.com/ABCrimson/modern-cmdk/blob/main/LICENSE) -- Copyright (c) 2026 Albert Badalov