A beautiful, accessible, and fully customizable command palette for Svelte 5 applications.
npm install svelte-command-palette#### Increase your productivity exponentially. 🚀🚀
A beautiful, accessible, and fully customizable command palette for Svelte 5 applications.
~2.1KB Minified | ~700B Gzipped

- 🔍 Fuzzy Search - Powered by Fuse.js for intelligent searching
- ⌨️ Keyboard Shortcuts - Define custom shortcuts for any action
- 🎨 Fully Customizable - Style every element with classes or inline styles
- 📱 Mobile Responsive - Bottom sheet UI on mobile devices
- ♿ Accessible - Full ARIA support and keyboard navigation
- 🎯 Conditional Actions - Run actions based on current state
- 📦 Action Grouping - Organize actions into logical groups
- 🔔 Event Callbacks - onOpen, onClose, onActionSelect hooks
- 🎭 Custom Empty State - Render custom UI when no results found
- 🌙 Dark Mode Ready - Built-in dark mode support
- 📝 TypeScript - Full type definitions included
- Svelte 5 Support - Fully migrated to Svelte 5 with runes ($props, $state, $effect, $derived)
- Customizable Trigger Shortcut - Change the default $mod+k to any shortcut
- Component Callbacks - onOpen, onClose, onActionSelect props
- Action Icons - Add icons to your actions
- Action Grouping - Group related actions together
- Custom Empty State - Provide a custom snippet for empty results
- Focus Trap - Keyboard focus stays within the palette
- Improved Accessibility - Better ARIA attributes and keyboard handling
- Type Exports - Export action type for TypeScript users
Version 2.0 is a complete rewrite for Svelte 5 and includes breaking changes:
| Change | v1.x (Svelte 3/4) | v2.x (Svelte 5) |
|--------|-------------------|-----------------|
| Svelte version | Svelte 3/4 | Svelte 5+ |
| Props syntax | export let | $props() runes |
| Event handlers | on:click | onclick |
| Slots | | {#snippet} / {@render} |
| Reactivity | $: statements | $derived, $effect |
shortcut - Customize the keyboard shortcut (default: $mod+k)onOpen - Callback when palette opensonClose - Callback when palette closes onActionSelect - Callback when an action is selectedemptyState - Custom snippet for empty resultsicon - Add an icon (emoji or string) to actionsgroup - Group related actions togetherIf you're still using Svelte 3 or 4, install the legacy version:
``bash`For Svelte 3/4 projects
npm install svelte-command-palette@1.2.1
The v1.x documentation is available at the v1.2.1 release.
| svelte-command-palette | Svelte Version |
|------------------------|----------------|
| ^2.0.0 | Svelte 5+ |^1.2.1
| | Svelte 3, 4 |
`bash`
npm install svelte-command-palette
`bash`
pnpm add svelte-command-palette
`bash`
yarn add svelte-command-palette
`svelte
placeholder="What would you like to do?"
shortcut="$mod+k"
onOpen={() => console.log('Palette opened')}
onClose={() => console.log('Palette closed')}
onActionSelect={(action) => console.log('Selected:', action.title)}
/>
`
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| commands | action[] | [] | Array of actions to display |placeholder
| | string | "Search for an action..." | Input placeholder text |shortcut
| | string | "$mod+k" | Keyboard shortcut to open palette |onOpen
| | () => void | - | Callback when palette opens |onClose
| | () => void | - | Callback when palette closes |onActionSelect
| | (action) => void | - | Callback when action is selected |unstyled
| | boolean | false | Disable default styles |emptyState
| | Snippet | - | Custom empty state content |
All styling props accept either a class name (string) or style object (Properties).
| Class Prop | Style Prop | Description |
|------------|------------|-------------|
| overlayClass | overlayStyle | Backdrop overlay |paletteWrapperInnerClass
| | paletteWrapperInnerStyle | Main palette container |inputClass
| | inputStyle | Search input |resultsContainerClass
| | resultsContainerStyle | Results list container |resultContainerClass
| | resultContainerStyle | Individual result item |optionSelectedClass
| | optionSelectedStyle | Active/selected result |titleClass
| | titleStyle | Result title |subtitleClass
| | subtitleStyle | Result subtitle |descriptionClass
| | descriptionStyle | Result description |keyboardButtonClass
| | keyboardButtonStyle | Keyboard shortcut badges |
Define actions using the defineActions helper:
`typescript`
type action = {
actionId?: string | number; // Unique identifier (auto-generated if not provided)
title: string; // Main display text (required)
subTitle?: string; // Secondary text
description?: string; // Additional description
keywords?: string[]; // Search keywords
shortcut?: string; // Keyboard shortcut (e.g., "$mod+k")
icon?: string | Snippet; // Icon (emoji, URL, or Snippet for custom SVG/component)
group?: string; // Group name for organizing actions
onRun?: (params) => void; // Callback when action is executed
canActionRun?: (params) => boolean; // Conditional execution
};
#### onRun and canActionRun Parameters
`typescript`
type onRunParams = {
action: action; // The current action
storeProps: storeParams; // Current store state
storeMethods: StoreMethods; // Store manipulation methods
};
Access palette controls from anywhere in your app:
`javascript
import { createStoreMethods } from 'svelte-command-palette';
const methods = createStoreMethods();
// Available methods:
methods.openPalette(); // Open the palette
methods.closePalette(); // Close the palette
methods.togglePalette(); // Toggle open/close
methods.resetPaletteStore(); // Reset to initial state
methods.getAllCalledActions(); // Get history of executed actions
methods.storeCalledAction(id); // Add action to history
methods.revertLastAction(id); // Remove last action from history
methods.resetActionLog(); // Clear action history
`
For advanced use cases, access the store directly:
`javascript
import { paletteStore } from 'svelte-command-palette';
// Subscribe to changes
paletteStore.subscribe(state => {
console.log('Palette visible:', state.isVisible);
console.log('Search text:', state.textInput);
console.log('Results:', state.results);
});
// Update directly
paletteStore.update(state => ({
...state,
isVisible: true
}));
`
`javascript`
const actions = defineActions([
{
title: 'Admin Panel',
subTitle: 'Only visible to admins',
canActionRun: ({ storeProps }) => {
return storeProps.user?.role === 'admin';
},
onRun: () => {
window.location.href = '/admin';
}
}
]);
`javascript`
const actions = defineActions([
{ title: 'Dashboard', group: 'Navigation', onRun: () => goto('/') },
{ title: 'Settings', group: 'Navigation', onRun: () => goto('/settings') },
{ title: 'Profile', group: 'User', onRun: () => goto('/profile') },
{ title: 'Logout', group: 'User', onRun: () => signOut() }
]);
The icon property supports multiple formats:
#### Emoji Icons
`javascript`
const actions = defineActions([
{ title: 'Settings', icon: '⚙️', onRun: () => {} },
{ title: 'Search', icon: '🔍', onRun: () => {} }
]);
#### Image URLs
`javascript`
const actions = defineActions([
{ title: 'GitHub', icon: 'https://github.com/favicon.ico', onRun: () => {} },
{ title: 'Logo', icon: '/images/logo.svg', onRun: () => {} }
]);
#### Custom SVG with Snippets
`svelte
{#snippet settingsIconSnippet()}
{/snippet}
`
#### Third-Party Icon Libraries (Lucide, Heroicons, etc.)
`svelte
{#snippet settingsIcon()}
{/snippet}
{#snippet searchIcon()}
{/snippet}
{#snippet userIcon()}
{/snippet}
`
` No results foundsvelte`
{#snippet emptyState()}
{/snippet}
`svelte`
overlayClass="bg-black/50 backdrop-blur-sm"
paletteWrapperInnerClass="bg-gray-900 rounded-xl shadow-2xl"
inputClass="bg-transparent text-white placeholder-gray-400"
resultContainerClass="hover:bg-gray-800 transition-colors"
optionSelectedClass="bg-blue-600"
inputStyle={{ fontSize: '18px' }}
/>
Use tinykeys syntax for shortcuts:
`javascript`
const actions = defineActions([
{ title: 'Save', shortcut: '$mod+s', onRun: save }, // Cmd+S / Ctrl+S
{ title: 'Undo', shortcut: '$mod+z', onRun: undo }, // Cmd+Z / Ctrl+Z
{ title: 'Search', shortcut: '$mod+Shift+f', onRun: search }, // Cmd+Shift+F
{ title: 'Help', shortcut: 'F1', onRun: showHelp } // F1
]);
| Key | Action |
|-----|--------|
| Cmd/Ctrl + K | Open/close palette (customizable) |↑
| / ↓ | Navigate through results |Enter
| | Execute selected action |Escape
| | Close palette |Tab
| | Cycle through focusable elements |
Full TypeScript support with exported types:
`typescript
import type { action, commands, storeParams, ActionId, onRunParams } from 'svelte-command-palette';
const myAction: action = {
title: 'My Action',
onRun: ({ action, storeProps, storeMethods }: onRunParams) => {
console.log(action.title);
}
};
`
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
Contributions are welcome! Please read our contributing guidelines before submitting a PR.
`bashClone the repo
git clone https://github.com/rohitpotato/svelte-command-palette.git
MIT © Rohit Kashyap
- Documentation
- GitHub
- npm