Phase 9d · Tier B
RN-universal Command pilot
ScaffoldedTypeahead-filtered command palette. Substring (case-insensitive) match in v1. Library decision: no new runtime dep — cmdk evaluated and rejected because it is web-only and would force a .web/.native split that no other 0.2.x primitive uses.
Side-by-side: app commands
shadcn (cmdk)
No results.
New file ⌘N
Open… ⌘O
Preferences ⌘,
RN
Type to filter; tap an item to select.
Library decision
Per Phase 9 Q2, every Tier B primitive must record its library choice. RnCommand ships with no new runtime dependency.
- cmdk@1.1.1 (MIT, ~39M/wk) — evaluated and rejected. cmdk is web-only (DOM portals, refs, focus trap) and would force a `.web/.native` split that no other 0.2.x primitive uses.
- This implementation — pure React Native primitives (`View`, `TextInput`, `ScrollView`, `Pressable`) plus a context-driven substring filter. Same mechanics as `RnAccordion` / `RnSelect`. Zero added bundle weight.
- Substring vs fuzzy — v1 is case-insensitive substring. Score-based fuzzy ranking is a 0.2.x candidate if a consumer reports the difference matters.
Semantics
| Aspect | shadcn (cmdk) | RN | Notes |
|---|---|---|---|
| Filter | fuzzy + score | substring (case-insensitive) | Custom filter prop overrides |
| Group hide | auto when empty | auto when no visible items | Same UX |
| Empty state | <CommandEmpty> | <RnCommandEmpty> | Shown when typed and 0 matches |
| Keyboard nav | arrow keys + Enter | tap (or Tab on RN-Web) | Arrow-key roving in v1+ |
| Item synonyms | value + keywords | value + searchText | searchText overrides label for filtering |
| Mounting | always mounted | visible items only | Hidden items return null |