Command Palette Developer
About
This skill provides comprehensive guidance for building professional command palette interfaces in React applications. It covers modern tooling like cmdk, Floating UI, and Tanstack Virtual for implementing keyboard-first search modals and navigation. Use it when developers need to create Raycast-style interfaces, ⌘K search, or command menus with TypeScript and Tailwind.
Quick Install
Claude Code
Recommended/plugin add https://github.com/majiayu000/claude-skill-registrygit clone https://github.com/majiayu000/claude-skill-registry.git ~/.claude/skills/Command Palette DeveloperCopy and paste this command in Claude Code to install this skill
Documentation
Command Palette Development
Build professional command palette interfaces for web applications using React, TypeScript, and Tailwind CSS. Command palettes provide keyboard-first navigation that enables power users to access functionality without leaving the keyboard, combining CLI efficiency with GUI discoverability.
Purpose & When to Use
Command palettes solve the tension between feature-rich applications and clean interfaces. Instead of cluttering screens with buttons and menus, palettes consolidate functionality into a searchable, keyboard-driven interface that appears on demand (typically via ⌘K or ⌘+Shift+P).
Use command palettes when building applications that:
- Have numerous actions or navigation targets (20+ commands)
- Serve power users who prefer keyboard workflows
- Need searchable, discoverable functionality
- Require context-aware command suggestions
- Want to provide multi-step command flows (e.g., select repository → choose action)
This skill provides generator scripts, templates, examples, and comprehensive guidance for implementing command palettes matching the quality of Raycast, Linear, GitHub, and Notion.
Choosing Implementation Patterns
Modal Palette - Centered overlay with backdrop (⌘K standard):
- Use for: App-wide actions, global search, navigation
- Examples: GitHub's command palette, VS Code's command palette
- Generated with:
create-command-palette.sh --type modal
Embedded Palette - Floating element attached to trigger:
- Use for: Contextual actions, inline search, form controls
- Examples: Notion's slash commands, mention autocomplete
- Generated with:
create-command-palette.sh --type embedded
Drawer Palette - Slide-in panel from screen edge:
- Use for: Filter panels, advanced search, settings navigation
- Examples: Raycast's Store, application settings
- Generated with:
create-command-palette.sh --type drawer
Quick Start Guide
1. Initial Setup
Install dependencies and create base configuration:
cd /path/to/your/project
/path/to/skills/command-palette-dev/scripts/setup-palette-stack.sh
This script:
- Detects your package manager (npm/pnpm/yarn/bun)
- Installs required packages:
cmdk,@floating-ui/react,zustand,@tanstack/react-query,@tanstack/react-virtual - Creates
ThemeProvider.tsxandCommandProvider.tsx - Sets up
command-registry.tsfor command registration - Adds Tailwind configuration for palette variants
- Validates existing dependencies and suggests remediation if issues found
2. Generate Your First Palette
Create a basic modal command palette:
./scripts/create-command-palette.sh \
--type modal \
--name SearchPalette \
--output ./src/components
This generates:
SearchPalette.tsx- Main component with keyboard navigationSearchPalette.types.ts- TypeScript interfacesindex.ts- Barrel export
3. Integrate into Application
Wrap your app with providers:
// src/App.tsx
import { ThemeProvider } from './providers/ThemeProvider';
import { CommandProvider } from './providers/CommandProvider';
import { SearchPalette } from './components/SearchPalette';
function App() {
return (
<ThemeProvider>
<CommandProvider>
<YourApp />
<SearchPalette />
</CommandProvider>
</ThemeProvider>
);
}
Register commands:
// Anywhere in your app
import { useCommandRegistry } from './providers/CommandProvider';
function MyComponent() {
const registry = useCommandRegistry();
useEffect(() => {
registry.register({
id: 'navigate-home',
label: 'Go to Dashboard',
keywords: ['home', 'dashboard', 'main'],
shortcut: 'g then d',
icon: HomeIcon,
onSelect: () => navigate('/'),
});
}, []);
}
4. Customize Layout and Results
Generate specific layout patterns:
# Two-column with preview panel (Raycast style)
./scripts/create-palette-layout.sh \
--layout two-column \
--name FileSearch \
--with-preview
# Card grid for rich results (Raycast Store style)
./scripts/create-palette-layout.sh \
--layout card-grid \
--name StorePalette \
--virtualized
Create typed result components:
# Person results with avatars
./scripts/create-result-type.sh \
--type person \
--name PersonResult
# File results with icons and metadata
./scripts/create-result-type.sh \
--type file \
--name FileResult \
--with-actions
Core Concepts
Command Palette Anatomy
Every command palette consists of four essential parts:
- Trigger - Keyboard shortcut or button that opens the palette (⌘K, ⌘+Shift+P)
- Input Field - Search box with real-time fuzzy filtering
- Results List - Filtered commands with keyboard navigation (arrow keys, enter)
- Footer (optional) - Keyboard legend showing available shortcuts
The cmdk library handles filtering, keyboard navigation, and accessibility automatically. Focus on command registration and result rendering.
Layout Patterns
Command palettes support multiple layout configurations depending on data richness and use case:
Single-Column List - Basic vertical list of results:
- Best for: Simple actions, text-heavy commands, mobile
- Performance: Excellent (handles 2,000-3,000 items)
- Reference:
references/layouts.mdfor implementation details
Two-Column with Preview - List on left, detail panel on right:
- Best for: Files, documents, rich content needing preview
- Examples: Raycast file search, GitHub repository picker
- Requires: Preview component that updates on selection change
Multi-Panel - Sidebar filters + center results + right details:
- Best for: Complex filtering, data tables, admin panels
- Examples: AWS console command palette
- Consideration: Responsive behavior on smaller screens
Card Grid - Rich cards with images, badges, metadata:
- Best for: Extensions, plugins, visual content
- Examples: Raycast Store, Figma plugin browser
- Requires: Virtual scrolling for 100+ items
Horizontal Cards + Lists - Mixed layout with scrollable cards and list items:
- Best for: Grouped content types, contextual results
- Examples: Linear's command palette
- Implementation: Combine multiple result type components
For detailed layout implementations and responsive strategies, see references/layouts.md.
Result Types
Different command types require different visual presentations:
- Person - Avatar, name, email/role, status indicators
- File - File type icon, name, size, modification date
- Action - Action icon, label, description, keyboard shortcut
- Card - Image, title, description, badges, metadata
Generate result components with create-result-type.sh to get type-safe, accessible implementations matching your design system.
State Management with Zustand
Command palettes maintain several state concerns:
interface CommandPaletteState {
isOpen: boolean; // Palette visibility
searchQuery: string; // Current search text
selectedId: string | null; // Active result
recentCommands: Command[]; // Usage history
favorites: string[]; // Pinned commands
commandStack: Command[]; // Multi-step navigation breadcrumb
}
The generated CommandProvider uses Zustand for lightweight, performant state management. For server-side search, Tanstack Query handles caching and loading states separately.
Detailed state patterns and integration with Tanstack Query are documented in references/state-management.md.
Theming System
All generated palettes support three theme modes:
- Light - Light backgrounds, dark text
- Dark - Dark backgrounds, light text
- System - Follows OS preference via
prefers-color-scheme
Themes use CSS variables for runtime switching without re-renders:
:root {
--palette-bg: white;
--palette-text: black;
}
[data-theme="dark"] {
--palette-bg: #1a1a1a;
--palette-text: white;
}
Tailwind's dark mode integrates seamlessly. For custom theme creation and per-palette overrides, see references/theming.md.
Generator Scripts Guide
Five generator scripts create components without reading templates into context:
create-command-palette.sh
Generate complete palette components:
./scripts/create-command-palette.sh \
--type modal|embedded|drawer \
--name ComponentName \
--output ./src/components \
--theme light|dark|system
Flags:
--type(required) - Palette variant: modal, embedded, drawer--name(required) - Component name in PascalCase--output(default: ./src/components) - Output directory--theme(default: system) - Theme mode--with-footer(default: true) - Include keyboard legend--with-groups(default: true) - Support command groups--interactive- Prompt for all options
create-palette-layout.sh
Generate layout-specific components:
./scripts/create-palette-layout.sh \
--layout single-column|two-column|multi-panel|card-grid|horizontal-cards \
--name ComponentName \
--virtualized
Flags:
--layout(required) - Layout pattern--name(required) - Component name--output(default: ./src/components) - Output directory--virtualized(default: false) - Enable Tanstack Virtual for 10k+ items--with-preview(default: true for two-column) - Add preview panel
create-result-type.sh
Generate typed result components:
./scripts/create-result-type.sh \
--type person|file|action|card \
--name ResultComponent \
--with-actions
Flags:
--type(required) - Result type--name(required) - Component name--output(default: ./src/components/results) - Output directory--with-avatar(default: true for person) - Include avatar--with-icon(default: true) - Include icon--with-metadata(default: true) - Include metadata line--with-actions(default: false) - Include inline action buttons
setup-palette-stack.sh
Initial project setup:
./scripts/setup-palette-stack.sh \
--project-root . \
--with-examples
What it does:
- Detects package manager
- Validates Node/TypeScript versions
- Installs dependencies with version compatibility check
- Creates provider components
- Initializes command registry
- Configures Tailwind for palettes
- Optionally copies working examples
add-palette-feature.sh
Add features to existing palettes:
./scripts/add-palette-feature.sh \
--feature virtual-scroll|server-search|keyboard-shortcuts|recent-commands|favorites|multi-step \
--target ./src/SearchPalette.tsx
Features:
virtual-scroll- Tanstack Virtual for 10k+ itemsserver-search- Tanstack Query integration with debouncingkeyboard-shortcuts- ⌘+1-9 favorites and custom bindingsrecent-commands- Track and display recent usagefavorites- Pin commands with persistencemulti-step- Nested command flows with breadcrumbs
Workflow Patterns
Basic palette creation:
setup-palette-stack.sh
create-command-palette.sh --type modal --name Actions
Rich file search:
create-palette-layout.sh --layout two-column --name FileSearch
create-result-type.sh --type file --name FileResult
add-palette-feature.sh --feature virtual-scroll --target FileSearch.tsx
API-driven search:
create-command-palette.sh --type modal --name ApiSearch
add-palette-feature.sh --feature server-search --target ApiSearch.tsx
Additional Resources
Reference Files
Comprehensive documentation in references/:
design-principles.md- UX patterns, fuzzy search, discovery, accessibility from researchlayouts.md- Detailed implementation guides for all five layout patternstheming.md- CSS variables, Tailwind integration, custom themes, reduced motionkeyboard-navigation.md- Arrow keys, shortcuts, focus traps, multi-key sequencesstate-management.md- Zustand patterns, command registry, Tanstack Query integrationserver-side-search.md- API integration, debouncing, pagination, infinite scrollvirtual-scrolling.md- Tanstack Virtual setup, performance benchmarks, dynamic heightstesting.md- Vitest + RTL unit tests, Playwright E2E, performance testingfloating-positioning.md- Floating UI middleware for embedded palettesplugin-system.md- Extensibility patterns, third-party command providersanalytics.md- Telemetry patterns (reference only, not in examples)
Example Implementations
Working examples in examples/:
file-search/- Virtual scroll, fuzzy search, file metadata, recent filesaction-palette/- Grouped actions, keyboard shortcuts, iconsnavigation/- Breadcrumbs, route groups, search historymulti-step/- Nested commands, command chaining, back navigation (Raycast-style)server-search/- API integration, Tanstack Query, debounce, loading statesvirtual-list/- 10k+ items, Tanstack Virtual, performance optimizations
Each example includes a README explaining what it demonstrates and key implementation details.
Utility Functions
Reusable TypeScript utilities in utilities/:
fuzzy-search.ts- Fuzzy matching, scoring, highlight renderingkeyboard-shortcuts.ts- Shortcut parsing, matching, hooks, display formattingcommand-registry.ts- Command registration API, searching, grouping, providerstheme-utils.ts- Theme detection, switching, CSS variable generation
Copy these files into your project and customize as needed.
Scripts Directory
All generator scripts with dependency validation:
create-command-palette.sh- Main palette generatorcreate-palette-layout.sh- Layout variantscreate-result-type.sh- Result componentssetup-palette-stack.sh- Initial project setupadd-palette-feature.sh- Feature additions
Scripts validate dependencies before generation and provide remediation steps for missing or incompatible packages.
Best Practices
Performance:
- Use virtual scrolling (Tanstack Virtual) for 1,000+ items
- Debounce server searches (300-500ms)
- Memoize result components to prevent re-renders
- Lazy load preview content
Accessibility:
- Maintain focus trap when palette is open
- Announce result count changes to screen readers
- Support keyboard-only navigation
- Respect
prefers-reduced-motion
User Experience:
- Show recent/frequent commands on open
- Provide empty state guidance for new users
- Display keyboard shortcuts next to commands
- Support fuzzy search for typo tolerance
Architecture:
- Keep command registration decentralized (register in feature components)
- Use Zustand for UI state, Tanstack Query for server state
- Separate result rendering from business logic
- Design for plugin extensibility from the start
For detailed guidance on each best practice, consult the relevant reference documentation.
Getting Help
Common Issues:
- Palette doesn't open - Check keyboard shortcut conflicts, verify trigger is registered
- Search not filtering - Ensure commands have
keywordsarray, check fuzzy search configuration - Results not rendering - Verify result type components are imported, check TypeScript types
- Poor performance - Enable virtual scrolling, check for unnecessary re-renders with React DevTools
Deep Dives:
- Layout not working as expected →
references/layouts.md - Theme not switching →
references/theming.md - Keyboard nav issues →
references/keyboard-navigation.md - Server search slow →
references/server-side-search.md - Testing failures →
references/testing.md
Extending:
- Adding custom result types →
create-result-type.sh --type custom - Third-party integrations →
references/plugin-system.md - Performance optimization →
references/virtual-scrolling.md - Analytics/telemetry →
references/analytics.md
GitHub Repository
Related Skills
content-collections
MetaThis skill provides a production-tested setup for Content Collections, a TypeScript-first tool that transforms Markdown/MDX files into type-safe data collections with Zod validation. Use it when building blogs, documentation sites, or content-heavy Vite + React applications to ensure type safety and automatic content validation. It covers everything from Vite plugin configuration and MDX compilation to deployment optimization and schema validation.
creating-opencode-plugins
MetaThis skill provides the structure and API specifications for creating OpenCode plugins that hook into 25+ event types like commands, files, and LSP operations. It offers implementation patterns for JavaScript/TypeScript modules that intercept and extend the AI assistant's lifecycle. Use it when you need to build event-driven plugins for monitoring, custom handling, or extending OpenCode's capabilities.
sglang
MetaSGLang is a high-performance LLM serving framework that specializes in fast, structured generation for JSON, regex, and agentic workflows using its RadixAttention prefix caching. It delivers significantly faster inference, especially for tasks with repeated prefixes, making it ideal for complex, structured outputs and multi-turn conversations. Choose SGLang over alternatives like vLLM when you need constrained decoding or are building applications with extensive prefix sharing.
evaluating-llms-harness
TestingThis Claude Skill runs the lm-evaluation-harness to benchmark LLMs across 60+ standardized academic tasks like MMLU and GSM8K. It's designed for developers to compare model quality, track training progress, or report academic results. The tool supports various backends including HuggingFace and vLLM models.
