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 +1 -1
- package/README.md +76 -172
- package/THIRD-PARTY-NOTICES.md +303 -0
- package/dist/codemod/bin.mjs +14 -0
- package/dist/codemod/chunk-jscodeshift.mjs +36210 -0
- package/dist/codemod/chunk-print-options.mjs +43 -0
- package/dist/codemod/chunk-worker.mjs +476 -0
- package/dist/codemod/cli.mjs +298 -43659
- package/dist/codemod/transforms/data-attrs.mjs +551 -38
- package/dist/codemod/transforms/forward-ref.mjs +197 -32
- package/dist/codemod/transforms/import-rewrite.mjs +389 -30
- package/dist/codemod/transforms/should-filter.mjs +199 -10
- package/dist/codemod/worker.mjs +1 -0
- package/dist/core/index.d.mts +6 -1
- package/dist/core/index.mjs +12 -4
- package/dist/react/chunk-dialog.mjs +237 -0
- package/dist/react/dialog.d.mts +18 -0
- package/dist/react/dialog.mjs +2 -0
- package/dist/react/index.d.mts +26 -334
- package/dist/react/index.mjs +54 -1377
- package/dist/react/styles.css +2 -2
- package/package.json +12 -18
- package/dist/codemod/cli.d.mts +0 -16
- package/dist/codemod/transforms/data-attrs.d.mts +0 -6
- package/dist/codemod/transforms/forward-ref.d.mts +0 -6
- package/dist/codemod/transforms/import-rewrite.d.mts +0 -6
- package/dist/codemod/transforms/should-filter.d.mts +0 -5
package/LICENSE
CHANGED
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
|
-
|
|
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';
|
|
44
|
-
import { Command } from 'modern-cmdk/react';
|
|
45
|
-
import 'modern-cmdk/
|
|
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
|
-
|
|
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
|
|
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: () =>
|
|
194
|
-
{ id: itemId('paste'), value: 'Paste', shortcut: 'Mod+V', onSelect: () =>
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
`
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
264
|
-
|
|
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`
|
|
270
|
-
| `data-attrs` |
|
|
271
|
-
| `forward-ref` |
|
|
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
|
-
|
|
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
|
-
|
|
278
|
-
`would change <file>` and the summary ends in `(dry run, nothing written)`:
|
|
193
|
+
### The deprecated `modern-cmdk` bin
|
|
279
194
|
|
|
280
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
305
|
-
|
|
306
|
-
---
|
|
211
|
+
## Related packages
|
|
307
212
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
| Package | Description |
|
|
213
|
+
| Package | Status |
|
|
311
214
|
|---|---|
|
|
312
|
-
| [`
|
|
313
|
-
| `modern-cmdk
|
|
314
|
-
| `
|
|
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
|
|
224
|
+
[MIT](https://github.com/ABCrimson/modern-cmdk/blob/main/LICENSE) -- Copyright (c) 2026 Albert Badalov
|